FoundRole Jobs - AI Job Search & Application Tracker
OfficialFoundRole MCP lets an AI assistant run a full job search and application workflow inside chat: search live jobs, get fact-checked insights, track applications, set reminders, manage alerts, and research career questions.
Search live job listings with filters for title, location, company, recency, remote, salary floor, H-1B sponsorship, match score, and ghost-posting risk
Fetch full job details including description, requirements, skills, benefits, salary benchmarks, resume match, H-1B/E-Verify signals, and job-trust analysis
Get personalized job recommendations ranked by fit from your resume and profile
Analyze external job postings (e.g., from LinkedIn or a careers page) for match, missing skills, sponsorship, ghost risk, and salary
Compare 2–4 jobs side by side on fit, pay, sponsorship, and posting risk
Track jobs on a Kanban board: add, list, update, change status, and remove tracked jobs
Set and delete follow-up reminders with email/calendar invites
Subscribe to, list, and unsubscribe from job alert emails (daily, weekly, monthly)
Search FoundRole's career knowledge base for interview prep, salary negotiation, resume tactics, and company research
List knowledge topics and categories covered by the career blog
Allows creating calendar reminders for job follow-ups, which can be added to Google Calendar via .ics files.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@FoundRole Jobs - AI Job Search & Application Trackerfind remote software engineer jobs posted this week"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
FoundRole MCP Server — AI Job Search in ChatGPT, Claude & Cursor
Ask ChatGPT or Claude for jobs and get real openings back — each one checked for whether it's still real, what it actually pays, and whether the company sponsors visas. The FoundRole MCP server connects your AI assistant to FoundRole's live job board, application tracker, and career knowledge base, so the whole job search runs inside the chat you already use.
Sign in once — your assistant handles it. The first time your AI calls FoundRole it opens a standard OAuth sign-in; approve it once in the browser and that covers everything: search, fact-checks, the tracker, reminders, and alerts. There is no API key to copy or rotate, and the account is free.
What your assistant can do
Search live jobs by asking. Openings straight from company career pages, refreshed hourly across 40+ industries. Natural language maps onto real filters — job title, location, company, salary range, posting date: "remote React jobs in NYC paying over $130k posted this week."
Get every posting fact-checked — free. Before you spend an evening on an application, three questions get answered with the evidence behind each call:
Is anyone actually hiring? Ghost-posting risk — whether the role has been reposted for months or looks like it's fishing for resumes.
Am I being underpaid? The pay against what employers in that market really file, so a hidden salary range stops being a guess.
Would they sponsor me? Whether the company has sponsored visas before, counted year by year from public filings.
See how well you fit. Match scoring against your resume and profile, plus personalized job recommendations ranked by fit.
See what hiring software reads off your resume — free. Ask, and you get back the version of you a parser extracts: job title, years, recognized skills, sections, contact details — plus what it loses on the way. It's the mechanical read, deterministic and repeatable, so the answer doesn't drift between asks. Paste the text into the chat, or check the resume already on your account.
Research before you commit. Dig into companies, industry sectors, and hiring by location to decide where to aim.
Compare roles side by side. "Compare these two" lines up fit, pay, sponsorship, and posting risk at once — so the choice stops being a feeling.
Paste a job from anywhere. LinkedIn, a careers page, a link a friend sent — paste the posting into the chat and it gets the same checks, and can sit in your tracker alongside FoundRole listings. Your assistant reads the text you provide; nothing crawls the site for you.
Stop losing track of applications. Save jobs to your Kanban application tracker and move them through Saved → Applied → Interviewing → Offered by asking, then archive each one with how it ended — hired, rejected, ghosted, or withdrawn. Attach notes, tags, the salary offered, and deadlines. The same board shows up in the web app.
Never miss a follow-up. Set a reminder on any tracked job and get an email with a calendar (
.ics) invite for Google Calendar, Outlook, or Apple Calendar.Let the search come to you. Subscribe a search to recurring email alerts — daily, weekly, or monthly — so new matches land in your inbox. Ask to list, change, or cancel them the same way.
Ask the awkward questions too. Interview prep, salary negotiation, resume tactics, company research — answers grounded in FoundRole's knowledge base, with the sources linked.
See results as real panels, not text walls. In clients that support MCP Apps (ChatGPT among them), search results, job details, and your tracker render as interactive panels right in the chat.
It's the same account and data as FoundRole.com — the MCP server just lets your AI drive it.
Related MCP server: jobs-winterchill-mcp
Free vs Pro
Search, the fact-checks on every posting, the tracker, reminders, and alerts are free with no usage limits. Screening filters work on every account: ask for remote-only, sponsors-only, a salary floor, risky postings hidden, a minimum match, specific benefits or employers, and your assistant filters the list before you ever see it — and tells you which filters ran. A free account gets the first few jobs that pass those filters, plus a count of how many more do; Pro returns the whole filtered list. Searches without screening filters come back in full on every account.
New here? The FoundRole AI Search guide walks through connecting each client step by step, with an FAQ.
Setup
Two ways to connect, depending on your client. Either way, your client opens a FoundRole sign-in the first time it connects — approve it once and you're set.
Option 1 — Remote server (recommended)
Point your client at the FoundRole MCP endpoint:
https://www.foundrole.com/mcpMost modern clients — ChatGPT, Claude, Cursor, VS Code — speak remote MCP (Streamable HTTP) natively, so this is all the configuration there is.
Option 2 — stdio bridge (for clients without remote MCP)
If your client only supports stdio transport, run this package locally with npx; it bridges stdio to the FoundRole endpoint and handles the OAuth sign-in for you:
npx @foundrole/ai-job-search-mcpThe first start opens FoundRole's sign-in page in your browser. After you approve, the bridge keeps the session in ~/.config/foundrole/mcp-auth.json (readable only by you) and renews it on its own, so later starts connect without asking again. Delete that file to sign out.
Connecting your AI assistant
ChatGPT
Estimated time: ~1 minute
Open FoundRole in the ChatGPT app directory.
Click Add and approve the FoundRole sign-in when ChatGPT opens it.
Ask for jobs in any chat — no settings to configure, nothing to paste.
Claude Web/Desktop
Estimated time: ~2 minutes
Open Claude settings (profile / settings icon).
Find Connectors (or Tools) and click Add custom connector.
Name it
FoundRole.In the Remote MCP server URL field, paste:
https://www.foundrole.com/mcpSave, allow Claude to connect, and approve the FoundRole sign-in it opens. Then ask for jobs in the chat.
Cursor
Estimated time: ~1 minute
Install the FoundRole plugin from the Cursor Marketplace: open Customize in the sidebar, find FoundRole, and select Install. Approve the FoundRole sign-in Cursor opens, then ask for jobs in any chat.
The plugin lives in this repository — .cursor-plugin/plugin.json with the server declared in mcp.json. To try it before it is listed, symlink this repo into ~/.cursor/plugins/local/ and reload the window.
Manual setup — Cursor / VS Code / Windsurf
In Cursor, open Settings → MCP and add this to ~/.cursor/mcp.json:
{
"mcpServers": {
"foundrole": {
"url": "https://www.foundrole.com/mcp"
}
}
}In VS Code, add this to .vscode/mcp.json in your workspace (or your user mcp.json) — VS Code uses a different key and needs an explicit transport type:
{
"servers": {
"foundrole": {
"type": "http",
"url": "https://www.foundrole.com/mcp"
}
}
}Approve the FoundRole sign-in when your editor opens it, then ask for jobs in the chat.
Antigravity (Google)
Estimated time: ~1 minute
Install the plugin straight from this repository:
agy plugin install https://github.com/foundrole/jobs-mcp-proxyApprove the FoundRole sign-in Antigravity opens, then ask for jobs in the CLI. The plugin declares the server in mcp_config.json; to wire it up by hand instead, add the same entry to ~/.gemini/config/mcp_config.json:
{
"mcpServers": {
"foundrole": {
"serverUrl": "https://www.foundrole.com/mcp"
}
}
}Any other MCP client
The same address works everywhere: add https://www.foundrole.com/mcp as a remote server, or bridge stdio-only clients with npx @foundrole/ai-job-search-mcp.
Note: After you approve the sign-in, some clients need a restart (quit and reopen) before the connection goes live.
Try saying
"Find senior backend engineer roles in San Francisco posted this week."
"Which of these is least likely to be a ghost posting?"
"Does Stripe sponsor visas? What does this role really pay?"
"Compare the Stripe and Vercel roles on fit, pay, and sponsorship."
"Here's a posting from LinkedIn — run the same checks on it."
"Recommend jobs that match my resume."
"Save it to my tracker and mark it Applied."
"Remind me to follow up next Tuesday morning."
"What's in my Interviewing column right now?"
"Subscribe me to weekly alerts for remote React jobs."
"How do I answer 'walk me through your resume'?"
Security
OAuth 2.1 with PKCE. You sign in to FoundRole through a standard authorization flow — short-lived tokens, instant revocation, no credentials shared with the AI client, no API key to copy, store, or leak.
HTTPS only, with dynamic client registration and redirect-URI validation.
Streamable HTTP transport (direct), or stdio via this proxy.
It never applies or emails anyone as you.
Troubleshooting
Asked to sign in / "needs authentication":
Expected on first connect — the server authenticates every session. Complete the FoundRole sign-in in the browser window your client opens.
If tools still don't appear afterward, restart the client or reconnect the connector so the authorization is re-sent.
"Connection failed":
Check your internet connection and that the URL is exactly
https://www.foundrole.com/mcp.Confirm your client supports remote HTTP MCP; if not, use the stdio bridge (Option 2).
"Command not found" (stdio clients):
Install Node.js (see
enginesinpackage.jsonfor the required version), then retry, or install globally:npm install -g @foundrole/ai-job-search-mcpand runai-job-search-mcp.
Connector not working:
Double-check the URL, complete the sign-in, and restart the AI client — some clients only pick up the connection after a restart.
Explore the data behind the answers
The same data your assistant reads is browsable on FoundRole:
How It Works — where the openings come from and how each posting gets its ghost, pay, and visa checks
H1B Salary Explorer — certified wages employers filed with the U.S. Department of Labor, charted by sector, industry, location, and role
H1B Sponsor Rankings — top visa-sponsoring companies by median filed wage, browsable by industry, sector, city, and state
Company Directory — open roles, salary data, and visa sponsorship history for any employer
Industry Sectors — who's hiring across 40+ industries
Hiring by Location — openings and wage benchmarks by state and metro
Job Tracker — the Kanban board your assistant manages, in the browser
Resume Checker — upload a resume and see what hiring software reads off it, section by section
Resume Builder — build a version per target role and export PDF, DOCX or TXT free, no watermark
Live Job Board — browse the listings directly
Help
🌐 Website: www.foundrole.com — free AI job search, application tracker, and company research
📖 Setup guide & FAQ: foundrole.com/ai-search-mcp
🐛 Issues: GitHub Issues
💬 Questions: dev@foundrole.com
Connect your AI client, sign in once, and run the whole job search from the chat — search, fact-checks, tracking, reminders, and alerts, free at FoundRole.
Made by the FoundRole team.
Available Tools
21 toolsjob_alert_listList job alertsARead-onlyInspect
Lists the authenticated user's job alerts across all subscription sources (regular, company page, MCP).
Input:
status: Filter by status — one of pending, active, unsubscribed (optional, default: all statuses)limit: Number of results to return (default 20, max 50)offset: Number of results to skip (default 0)
Output: Returns the user's job alerts with pagination info and a summary of the underlying job search (query, location, company where available). Each response includes a system_instruction describing how to present the results for the current client.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of results to return (default 20, max 50) | |
| offset | No | Number of results to skip (default 0) | |
| status | No | Filter by status: pending, active, unsubscribed |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| jobAlerts | No | |
| totalCount | No | |
| frequencies | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, so the safety profile is covered. The description adds real value beyond that: it discloses pagination behavior and, notably, that each response includes a system_instruction telling the client how to present results — non-obvious behavioral context.
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?
Front-loaded with the purpose, then cleanly sectioned into Input and Output blocks. It is slightly redundant with the input schema (limit/offset/status repeated verbatim), but not verbose and every section is easy to scan.
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 (3 optional params, no nesting) and an output schema exists, so return values need not be explained. The description still covers filtering, pagination and the system_instruction behavior, leaving little an agent would need to guess at.
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 description largely restates the same limit/offset/status details. It adds only a marginal clarification (status default is "all statuses" and that all three params are optional). Baseline 3 is appropriate when the schema already documents every parameter.
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 concrete verb and resource ("Lists the authenticated user's job alerts") and adds meaningful scope ("across all subscription sources (regular, company page, MCP)") that goes beyond the name. It does not explicitly contrast itself with siblings like jobs_recommendations or jobs_search, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies this is the way to enumerate the user's own alerts, but gives no explicit when-to-use guidance, no exclusions, and no pointer to alternatives such as jobs_recommendations. Usage is inferable from the name and scope rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
job_alert_subscribeCreate a job alertAIdempotentInspect
Subscribes the authenticated user to job alerts for a specific saved job search.
Input:
job_search_id: The job search identifier to subscribe to (required). Accepts either the job search UUID or the composite job ID returned byjobs_search/jobs_details(format: "seo_id--job_search_id").frequency: Alert frequency — one of daily, weekly, monthly (optional, defaults to "weekly")
Output: Returns the created or updated job alert with id, status, and frequency. Idempotent: calling this tool for an already-subscribed search updates the existing alert without creating a duplicate. An existing active alert with the same query text, location, company and filters, and at least the same radius, is returned instead of a new one, with the requested frequency applied to it.
Delivery:
All of a user's alerts arrive together in one email digest, one section per alert. Each section applies every filter and the sort of its saved search, the same way jobs_search does; Pro-only filters apply while the user has Pro. A job appears in the digest once, even when it matches several alerts, and no email is sent when there are no new matches. The digest follows the most frequent alert, and arrives less often when the user has not used FoundRole for a while.
| Name | Required | Description | Default |
|---|---|---|---|
| frequency | No | Alert frequency: daily, weekly, monthly (defaults to "weekly") | |
| job_search_id | Yes | Job search UUID or composite job id ("seo_id--job_search_id") from jobs_search results |
Output Schema
| Name | Required | Description |
|---|---|---|
| jobAlert | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare idempotentHint=true and destructiveHint=false, but the description goes well beyond them: it spells out the exact idempotency rule (existing alert matched on query text, location, company, filters, and at least the same radius), that the requested frequency is applied to the returned alert, and the delivery semantics (one digest, deduplicated jobs, Pro-only filters, cadence).
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?
Bold section headers (Input/Output/Delivery) front-load the purpose and required parameter, and the Input/Output blocks earn their place. The Delivery paragraph is informative but longer than needed to select and invoke this tool, describing email behavior that doesn't change the call itself.
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?
With an output schema present, return values need not be explained, yet the description still covers idempotency, default frequency, accepted ID formats, and downstream delivery effects. Nothing an agent needs to invoke 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 description coverage is 100%, so both parameters are already documented, and the description largely restates them (UUID vs composite ID format, default 'weekly'). It adds no syntax or validation detail the schema lacks, so the baseline 3 applies.
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 — 'Subscribes the authenticated user to job alerts for a specific saved job search' — which cleanly separates it from job_alert_unsubscribe, job_alert_unsubscribe_all, and job_alert_list. An agent can identify the action without opening the schema.
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 clear context for use (subscribe to a saved job search) and points to jobs_search / jobs_details as the source of the accepted composite ID format. It does not explicitly state when to prefer this over the unsubscribe siblings or what prerequisites apply, so it stops short of a full when/when-not statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
job_alert_unsubscribeUnsubscribe from a job alertADestructiveInspect
Unsubscribes the authenticated user from job alerts for a specific job search.
Input:
job_search_id: The job search identifier to unsubscribe from (required). Accepts either the job search UUID or the composite job ID returned byjobs_search/jobs_details(format: "seo_id--job_search_id").
Output: Confirms the alert has been unsubscribed. Idempotent: returns success even when the user was not subscribed or is already unsubscribed.
| Name | Required | Description | Default |
|---|---|---|---|
| job_search_id | Yes | Job search UUID or composite job id ("seo_id--job_search_id") from jobs_search results |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | |
| success | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false. The description adds genuinely new behavioral context: the operation is idempotent and returns success even if the user was never subscribed. That is not derivable from the 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?
Front-loaded single-sentence purpose followed by tight input/output notes. Every sentence earns its place; no filler or redundancy.
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?
An output schema exists, so return-format detail is unnecessary. The description covers the required input's accepted forms and the idempotency edge case, leaving little an agent needs beyond it.
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 schema already documents the job_search_id format. The description restates the same UUID/composite-ID detail without adding syntax or validation info beyond it; baseline 3 applies.
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: 'Unsubscribes the authenticated user from job alerts for a specific job search.' The 'specific job search' scope implicitly separates it from the sibling job_alert_unsubscribe_all, though it never names that sibling.
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?
Usage is implied by the description's scope and the parameter explanation, but there is no explicit when-to-use vs. when-to-use-alternative statement, and the obvious alternative (job_alert_unsubscribe_all) is never referenced.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
job_alert_unsubscribe_allUnsubscribe from all job alertsADestructiveIdempotentInspect
Unsubscribes the authenticated user from ALL of their job alerts at once, across every subscription source (regular, company page, MCP).
Input:
confirm: Must betrueto execute. The call is rejected when omitted or not true — this guards against an unintended bulk unsubscribe.
Output: Confirms how many alerts were unsubscribed. Idempotent: returns success even when the user has no active alerts.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | Yes | Set to true to confirm unsubscribing from every alert; the call is rejected otherwise |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | No | |
| success | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=true, so the safety profile is covered. The description adds genuinely new context: the confirm guard's rejection behavior and the explicit idempotency claim ('returns success even when the user has no active alerts') plus the source coverage.
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?
Front-loaded purpose sentence followed by tight Input/Output sections. Every sentence carries distinct information with no redundancy.
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 single-parameter bulk mutation, the description covers the confirm requirement, the safety rationale, source scope, and idempotency, while the output schema carries the return value. Nothing needed to call it 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% and the single parameter is documented there, so baseline is 3. The description adds the rationale behind the guard ('guards against an unintended bulk unsubscribe'), giving the agent the meaning of the flag beyond its schema text.
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?
Specific verb + resource + scope: 'Unsubscribes the authenticated user from ALL of their job alerts at once, across every subscription source.' It clearly distinguishes itself from the singular sibling job_alert_unsubscribe by emphasizing the bulk/all scope.
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 'ALL ... at once' framing implicitly routes the agent away from the single-alert sibling, and it enumerates the subscription sources covered. However, it never explicitly names job_alert_unsubscribe as the alternative for single-alert cases, so exclusion guidance is inferential.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jobs_analyze_externalAnalyze a job from another siteAInspect
Analyzes one job found outside FoundRole using the authenticated user's FoundRole profile and the same signals used for FoundRole jobs: resume match, missing skills, H-1B sponsorship history, E-Verify, ghost-job risk, posted compensation, and market salary estimates. Use tracker_add_external only when the user asks to save without analysis.
The input represents the direct posting URL and all job content already available in the conversation.
The five text identity fields are required; every structured fact field is optional, with a fact the
source does not state simply omitted (or null). The optional client_extraction object carries
evidence-backed skills, technology, benefits, bonuses, seniority, industry, management, clearance,
visa, and remote-scope labels when source excerpts for them exist. FoundRole validates the evidence,
stores the client extraction separately, derives missing deterministic facts, and reports which
values were provided, derived, accepted, rejected, or remain unknown.
The output includes comparisonRef; retain it exactly for a later jobs_compare call. The analysis is a
decision aid, not a guarantee about sponsorship, legitimacy, compensation, or hiring outcome.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Direct URL of the specific job posting; a company homepage is invalid | |
| posted_at | No | Posting date as ISO 8601, when the source states it | |
| title_name | Yes | Job title from the posting | |
| description | Yes | Complete posting text available in the conversation; a source summary is valid only when no fuller posting text is available | |
| salary_type | No | Salary period: year, month, week, day, hour | |
| company_name | Yes | Company name from the posting | |
| salary_value | No | Single salary amount, when the posting gives one figure instead of a range | |
| location_name | Yes | Location text from the posting, including Remote when stated | |
| employment_type | No | Employment types: full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other | |
| salary_currency | No | ISO 4217 salary currency code, when stated | |
| salary_max_value | No | Salary range maximum, when stated | |
| salary_min_value | No | Salary range minimum, when stated | |
| client_extraction | No | Evidence-backed facts extracted by the client model from the posting; non-null evidence is a short source excerpt rather than an inference. Fields absent from the source are omitted or null. | |
| experience_months | No | Minimum required experience in months, when stated | |
| work_location_type | No | Work arrangement: on_site, remote, hybrid | |
| education_requirements | No | Education requirements: no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree |
Output Schema
| Name | Required | Description |
|---|---|---|
| jobs | Yes | |
| mode | Yes | |
| studioUrl | No | |
| statusOrder | Yes | |
| derivedFields | Yes | |
| trackerWebUrl | Yes | |
| unknownFields | Yes | |
| providedFields | Yes | |
| clientExtraction | Yes | |
| system_instruction | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=false/destructiveHint=false/openWorldHint=false. The description goes well beyond that: it states what FoundRole does server-side (validates evidence, stores client extraction separately, derives missing deterministic facts, reports provided/derived/accepted/rejected/unknown), and candidly frames the analysis as a decision aid rather than a guarantee.
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 purpose is front-loaded and the routing instruction sits near the top where it matters. Three paragraphs is somewhat long and the middle paragraph is dense, but each block carries distinct information with little filler.
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 16-parameter, output-schema-backed tool, the description covers the input contract conventions, the server-side validation semantics, the comparisonRef handoff, and the limits of the result. Nothing an agent needs to invoke it 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 already 100%, so the baseline is 3, but the description adds genuine meaning: the five text identity fields are required while every structured fact is optional and simply omitted/null when the source is silent, and client_extraction labels must be evidence-backed. These rules are not obvious from the schema alone.
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 opening sentence gives a specific verb and resource ('Analyzes one job found outside FoundRole') and enumerates the exact signals computed (resume match, missing skills, H-1B history, E-Verify, ghost-job risk, compensation, market salary). It is clearly distinguishable from sibling tools like jobs_details and tracker_add_external.
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 routes the agent explicitly away from this tool in one case ('Use tracker_add_external only when the user asks to save without analysis') and forward to jobs_compare via comparisonRef. That is real when/when-not guidance, though it doesn't differentiate from jobs_details or jobs_search.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jobs_compareCompare jobsARead-onlyInspect
Compares 2 to 4 jobs side by side using the same FoundRole analysis fields: resume match, missing skills, H-1B and E-Verify signals, ghost-job risk, posted pay, and market salary estimates.
comparison_refs accepts exact FoundRole job IDs returned by jobs_search and exact external
comparisonRef URLs returned by jobs_analyze_external. Analyze each outside job first; a bare URL that
has not been analyzed cannot be compared because FoundRole does not have its posting facts. Preserve
every reference exactly, keep the user's requested order, and do not send duplicates.
| Name | Required | Description | Default |
|---|---|---|---|
| comparison_refs | Yes | Two to four exact FoundRole job IDs or external comparisonRef URLs |
Output Schema
| Name | Required | Description |
|---|---|---|
| jobs | Yes | |
| mode | Yes | |
| studioUrl | No | |
| statusOrder | Yes | |
| trackerWebUrl | Yes | |
| system_instruction | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish this is a read-only, non-destructive, closed-world operation, so the safety profile is covered. The description adds real behavioral context beyond that: a 2-4 reference bound, the requirement to preserve exact reference strings and user order, and a no-duplicates constraint. It stops short of describing what the comparison output looks like, though an output schema exists.
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 core action and field list are front-loaded in the first sentence, with the reference-format guidance second. Two paragraphs with no filler; slightly dense but every sentence carries a constraint the agent must honor.
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 single-parameter read tool with an output schema and full annotation coverage, the description supplies everything else needed: input provenance, prerequisite analysis step, count bounds, ordering, and dedup. Nothing an agent needs to invoke it 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 description coverage is 100% and the single parameter is documented with minItems/maxItems, so the baseline is 3. The description adds meaning the schema cannot: the two distinct reference types (FoundRole job IDs vs external comparisonRef URLs), the requirement to pass them exactly, and the ordering/dedup rules.
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 ('compares 2 to 4 jobs side by side') and enumerates the exact analysis dimensions returned (resume match, missing skills, H-1B/E-Verify, ghost-job risk, pay, salary estimates). This clearly separates it from jobs_details and jobs_analyze_external, which handle single jobs.
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 routes the agent: it names jobs_search as the source of job IDs and jobs_analyze_external as the source of external comparisonRef URLs, and states the prerequisite that an outside job must be analyzed first. It also states the failure condition — a bare unanalyzed URL cannot be compared — which is exactly the when-not guidance an agent needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jobs_detailsGet job detailsAInspect
Fetches full details for one job by the id returned from jobs_search — the deeper view behind a search result.
Input:
job_id: The exact ID string from theidfield of ajobs_searchresult.result_item_id: The matching occurrence ID from that result'sresultItemIdfield, when available.
Output:
Complete job details: description, skills, benefits, requirements, salary benchmark, resume match,
H-1B and E-Verify signals, job-trust analysis, and application link. A posting that passed the
fully-remote check carries remoteCheck: the posting lines that make the role remote and where
the employee may work from, or an unknown scope when the posting does not say. Personalized and extended
insight fields follow the authenticated user's current entitlements.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | Yes | The unique identifier of the job from jobs_search results | |
| result_item_id | No | The result occurrence ID returned with the selected job |
Output Schema
| Name | Required | Description |
|---|---|---|
| job | No | |
| studioUrl | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackerWebUrl | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false, yet the description describes a pure fetch — a mild tension worth noting, though not a hard contradiction since personalization/entitlement resolution can be non-read-only. The description does add real context beyond annotations (entitlement-dependent fields, the remoteCheck payload semantics), but it does not clarify auth requirements or why the tool is not read-only.
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?
Front-loaded with the core action, then cleanly separated into Input and Output blocks that are easy to scan. It is slightly long, but the Output section carries non-obvious information (entitlement gating, remoteCheck shape) rather than filler.
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?
With an output schema present, the description is not obligated to enumerate return fields, yet it still summarizes them usefully and clarifies the conditional remoteCheck field. Missing only auth/entitlement prerequisites for a tool whose results vary by the authenticated user.
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, and the description earns an increment by tying each parameter to its originating field in a jobs_search result (`id` and `resultItemId`), which the schema itself does not establish. It adds genuine cross-tool semantics rather than restating types.
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+resource ('Fetches full details for one job') and explicitly anchors it to the `id` returned from jobs_search. An agent can distinguish it from jobs_search, jobs_compare, and jobs_analyze_external without opening any schema.
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?
Frames the tool as 'the deeper view behind a search result,' which implies the correct usage sequence (search first, then fetch details by ID). It does not state exclusions or name a competing sibling for retrieving a single job, so it stops short of the explicit when/when-not guidance a 5 requires.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jobs_recommendationsRecommend jobs for my profileAIdempotentInspect
Returns the authenticated user's personalized job recommendations built from their resume, skills, target roles, and preferred location. Results are ranked by fit, may include related roles, and carry the same salary, match, H-1B, and job-trust insight payload used by job search. The search filters and sort parameters apply to this personalized feed too. Advanced parameters return a matching preview and hidden count for free accounts; Pro accounts receive the complete filtered list. An explicit query for a different or unrecognized profession uses the same general job search as jobs_search, preserving the query and filters instead of substituting the profile's target roles.
A processing status means the personalized feed is still being prepared; a later call returns the completed feed. Page numbers fetch additional recommendations from the same feed.
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Recommendation page number | |
| sort | No | Result order (score, posted_at, match, salary): score is relevance and the default, posted_at is newest first, salary is highest pay first, match is best personal fit first and needs a resume. Ordering by salary or match is an advanced option. | |
| query | No | The full job title or skill (e.g., "Ruby Developer", NOT just "Ruby") | |
| radius | No | Search radius in miles around a city location (default 40); not used for state, country or remote searches. | |
| remote | No | Advanced filter: only remote-eligible jobs, matched across the whole country of the requested location rather than its radius. | |
| company | No | The official company name | |
| benefits | No | Advanced filter: benefit names such as "health insurance", "401k" or "parental leave"; a job qualifies only when it states every listed benefit. Names that match no known benefit are ignored. | |
| location | No | Geographic location (e.g., 'Boston, MA') | |
| companies | No | Filter: official company names; a job from any of them qualifies, across every job board each employer posts on. More than one company makes it an advanced filter. Next to company, a job has to match both; hiring_brand narrows company only. | |
| education | No | Filter: jobs whose posting requires one of these education levels (no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree); bachelor_degree means the posting asks for a bachelor degree, not that it suits someone holding one. | |
| min_match | No | Advanced filter: lowest personal FoundRole match grade to keep, the same letter each job shows in insights.match.grade. A and A- are rare even for a strong resume; B keeps good and strong matches; C+ also keeps fair ones. Needs a resume on the account. | |
| work_modes | No | Advanced filter: jobs in any of these work modes (on_site, remote, hybrid). remote is matched across the whole country of the location, the others within the radius. ["remote"] is the same search as remote: true. | |
| bonuses_only | No | Advanced filter: only jobs that state a bonus (sign-on, performance, referral, commission and the like). | |
| hiring_brand | No | Filter: one brand inside the company, for example company "Google" with hiring_brand "YouTube"; used only together with company. | |
| salary_floor | No | Advanced filter: minimum annualized salary in USD; a posting qualifies when the lower bound of its pay band reaches the floor. Jobs without a USD salary are dropped. | |
| strict_remote | No | Advanced filter: only postings checked as fully remote that can be worked from the requested location: the posting names that area, allows anywhere, or does not say where. Stricter than remote; work_modes other than remote do not apply with it. | |
| posted_days_ago | No | Number of days ago to search for jobs (1-365) | |
| employment_types | No | Filter: jobs offered as any of these employment types (full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other). | |
| hide_low_quality | No | Advanced filter: hides postings with a risky ghost grade (D/F); ungraded postings stay. | |
| exclude_companies | No | Advanced filter: official company names whose jobs are removed from the results, across every job board each employer posts on. | |
| experience_levels | No | Filter: jobs at any of these experience levels (entry_level, mid_level, senior_level, executive). The level comes from the years of experience the posting asks for and the seniority in its title, the higher of the two; entry_level never includes a posting asking for more than two years. | |
| h1b_sponsors_only | No | Advanced filter: only companies known to sponsor H1B visas. | |
| confirmed_work_from | No | Advanced filter: with strict_remote, also leaves out postings that do not say where the work can be done from. |
Output Schema
| Name | Required | Description |
|---|---|---|
| jobs | No | |
| preview | No | |
| feedKind | No | |
| nextPage | No | |
| feedStatus | No | |
| totalCount | No | |
| continueUrl | No | |
| jobSearchId | No | |
| resultSetId | No | |
| statusOrder | No | |
| revalidating | No | |
| resultBatchId | No | |
| trackerWebUrl | No | |
| profileSetupUrl | No | |
| profileSetupState | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial context beyond the annotations: results are fit-ranked, may include related roles, carry the same insights payload as search, and free vs Pro accounts receive different result completeness (preview plus hidden count vs the full filtered list). It also documents the asynchronous processing status and that a later call returns the completed feed, which the annotations (idempotent, non-destructive, closed-world) do not convey.
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?
Front-loads the core purpose, then ambient behavior (ranking, insights), then tiering, then the jobs_search fallback and pagination/status semantics. Three compact paragraphs with little waste, though slightly longer than strictly needed for a read-style tool.
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?
With an output schema present, return values need not be described, and the description covers the remaining gaps an agent needs: what determines the feed, tier-gated completeness, async processing, pagination continuity, and the fallback search path. Nothing material for correct invocation 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% across 23 params, so the schema carries the per-parameter burden (baseline 3). The description still adds non-obvious parameter behavior: the search filters and sort apply to the personalized feed, and advanced parameters change output scope by account tier, which the schema does not state.
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?
Names a specific verb and resource — returns the authenticated user's personalized job recommendations — and states the inputs that build them (resume, skills, target roles, preferred location). It also distinguishes itself from jobs_search by explaining the fallback path when an explicit query names a different or unrecognized profession.
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 routing: an explicit query outside the profile's target roles routes to the same general search as jobs_search rather than substituting the profile. It also notes how pages retrieve more of the same feed and what a processing status means. It stops short of stating outright when to prefer this over jobs_search for a normal query.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jobs_searchSearch jobsAInspect
Searches a database for real-time job listings matching the user's criteria.
The query is the full job title or role: "Ruby Developer" or "Ruby on Rails Engineer" rather than a bare keyword like "Ruby", which is too broad and matches unrelated fields. Results may be filtered by location, company, and how recently a job was posted.
Each result carries an id and resultItemId; jobs_details takes that id with the corresponding
result_item_id and returns the job's full description, requirements, and benefits. The response also carries a nextCursor for the next page of
results; a follow-up page is fetched by passing only that cursor, with no other search parameters.
With a ready profile, a query for the profile's target profession or an omitted query uses the same personalized feed as jobs_recommendations and the website. A different or unrecognized profession uses general job search, preserving the explicit query and filters. An omitted location uses the profile location. Without a ready profile, search uses the general job listings. Job details include FoundRole salary benchmarks, H-1B sponsorship signals, E-Verify status, and job-trust analysis; list-level employer signals follow the user's current entitlements.
Constraints in the user's request — remote-only work, H1B sponsorship, a minimum salary, hiding risky postings, a minimum match grade — are the search parameters remote, h1b_sponsors_only, salary_floor, hide_low_quality, and min_match; sort orders the results by relevance, newest, salary or personal match. The search enforces only constraints passed as parameters; a constraint left out of the call is not applied to the result set.
Job type, work mode, required education, experience level, benefits, bonuses, employers to include or exclude, and the search radius are the parameters employment_types, work_modes, education, experience_levels, benefits, bonuses_only, companies, exclude_companies and radius. Remote and hybrid are independent work modes: a remote search never returns hybrid jobs. A job that does not state the filtered attribute is left out while that filter is set. Fully remote work that can be done from the requested location is strict_remote, with confirmed_work_from to require a stated work-from area; one brand inside a company is hiring_brand next to company.
Advanced filters (sort, min_match, h1b_sponsors_only, hide_low_quality, salary_floor, remote, strict_remote, confirmed_work_from, work_modes, benefits, bonuses_only, companies, exclude_companies; sort only when ordering by salary or match, companies only when it names more than one employer) apply for every account. Without FoundRole Pro, a search using one returns the first few matching jobs and the number of further matches; FoundRole Pro accounts receive the whole list. The other parameters never shorten the results.
Each response includes a system_instruction describing how to present the results for the current client.
| Name | Required | Description | Default |
|---|---|---|---|
| sort | No | Result order (score, posted_at, match, salary): score is relevance and the default, posted_at is newest first, salary is highest pay first, match is best personal fit first and needs a resume. Ordering by salary or match is an advanced option. | |
| query | No | The full job title or skill (e.g., "Ruby Developer", NOT just "Ruby") | |
| cursor | No | Pagination cursor. Treat as an opaque string. COPY EXACTLY. | |
| radius | No | Search radius in miles around a city location (default 40); not used for state, country or remote searches. | |
| remote | No | Advanced filter: only remote-eligible jobs, matched across the whole country of the requested location rather than its radius. | |
| company | No | The official company name | |
| benefits | No | Advanced filter: benefit names such as "health insurance", "401k" or "parental leave"; a job qualifies only when it states every listed benefit. Names that match no known benefit are ignored. | |
| location | No | Geographic location (e.g., 'Boston, MA') | |
| companies | No | Filter: official company names; a job from any of them qualifies, across every job board each employer posts on. More than one company makes it an advanced filter. Next to company, a job has to match both; hiring_brand narrows company only. | |
| education | No | Filter: jobs whose posting requires one of these education levels (no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree); bachelor_degree means the posting asks for a bachelor degree, not that it suits someone holding one. | |
| min_match | No | Advanced filter: lowest personal FoundRole match grade to keep, the same letter each job shows in insights.match.grade. A and A- are rare even for a strong resume; B keeps good and strong matches; C+ also keeps fair ones. Needs a resume on the account. | |
| work_modes | No | Advanced filter: jobs in any of these work modes (on_site, remote, hybrid). remote is matched across the whole country of the location, the others within the radius. ["remote"] is the same search as remote: true. | |
| bonuses_only | No | Advanced filter: only jobs that state a bonus (sign-on, performance, referral, commission and the like). | |
| hiring_brand | No | Filter: one brand inside the company, for example company "Google" with hiring_brand "YouTube"; used only together with company. | |
| salary_floor | No | Advanced filter: minimum annualized salary in USD; a posting qualifies when the lower bound of its pay band reaches the floor. Jobs without a USD salary are dropped. | |
| strict_remote | No | Advanced filter: only postings checked as fully remote that can be worked from the requested location: the posting names that area, allows anywhere, or does not say where. Stricter than remote; work_modes other than remote do not apply with it. | |
| posted_days_ago | No | Number of days ago to search for jobs (1-365) | |
| employment_types | No | Filter: jobs offered as any of these employment types (full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other). | |
| hide_low_quality | No | Advanced filter: hides postings with a risky ghost grade (D/F); ungraded postings stay. | |
| exclude_companies | No | Advanced filter: official company names whose jobs are removed from the results, across every job board each employer posts on. | |
| experience_levels | No | Filter: jobs at any of these experience levels (entry_level, mid_level, senior_level, executive). The level comes from the years of experience the posting asks for and the seniority in its title, the higher of the two; entry_level never includes a posting asking for more than two years. | |
| h1b_sponsors_only | No | Advanced filter: only companies known to sponsor H1B visas. | |
| confirmed_work_from | No | Advanced filter: with strict_remote, also leaves out postings that do not say where the work can be done from. |
Output Schema
| Name | Required | Description |
|---|---|---|
| jobs | No | |
| preview | No | |
| feedKind | No | |
| feedStatus | No | |
| continueUrl | No | |
| jobSearchId | No | |
| resultSetId | No | |
| statusOrder | No | |
| revalidating | No | |
| resultBatchId | No | |
| trackerWebUrl | No | |
| profileSetupUrl | No | |
| profileSetupState | No | |
| lowRelevanceNotice | No | |
| system_instruction | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations carry only readOnlyHint/openWorldHint/destructiveHint, so the description does the heavy lifting: it discloses pagination via nextCursor and the cursor-only protocol, entitlements-gated result truncation for non-Pro accounts, profile-driven personalization, strict_remote vs remote semantics, and that constraints left out of the call are simply not applied. This is far beyond what the annotations provide.
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 content is valuable but the middle and later paragraphs largely restate semantics already encoded in the 100%-covered schema (work_modes vs remote independence, strict_remote/confirmed_work_from, the advanced-filter list), producing a dense wall of text with meaningful redundancy. Front-loading is good, but several sentences do not earn their place against the schema.
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 23-parameter, zero-required search tool with an output schema, the description covers the remaining unknowns an agent needs: profile/entitlement behavior, pagination protocol, the id-to-jobs_details handoff, and the fact that omitted constraints are not applied. Return-value explanation is correctly delegated to the output schema.
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%, yet the description still adds mapping value by translating natural-language constraints (remote-only work, H1B sponsorship, salary floor, hiding risky postings) onto the exact parameter names remote, h1b_sponsors_only, salary_floor, hide_low_quality, min_match, and by noting sort only when ordering by salary/match and companies only for multiple employers.
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 opening sentence states a specific verb and resource — 'Searches a database for real-time job listings' — and the rest of the description makes clear how it differs from jobs_recommendations, jobs_details, and jobs_analyze_external. An agent can select it without opening any sibling schema.
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?
Explicit routing rules: use jobs_details with a result's `id`/`resultItemId` for full posting text; an omitted or profession-matching query falls into the same personalized feed as jobs_recommendations; a different profession falls back to general search. It also states when advanced filters apply and what happens without Pro.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
knowledge_searchSearch career guidesARead-onlyIdempotentInspect
Searches FoundRole's published content by semantic similarity and returns the most relevant sources for a job-search question: career-guidance blog articles plus FoundRole site pages that describe the product's features (job tracker, Pro plan and pricing, H1B salary data, AI job search) and industry/sector career landings. Each article carries a title, url, summary, a content excerpt, publication date, and tags; each page carries a title, url, description, and its FAQ entries — enough material to answer the question and link the source.
Two optional facets add further result groups: company returns FoundRole's employer profile pages matching that company name; location returns the market landing page for that city, state, or country — an analytical page about that labour market, not a list of openings. The facets describe what the user is asking about — a company mentioned only in passing does not need the company facet.
Returns empty groups when nothing is relevant rather than padding with off-topic content. Results are the closest matches to the given question, not an index of the site's full coverage; questions about overall topic coverage are answered by knowledge_topics, which lists the blog's categories and tags with article counts. It does not search job listings and reports no open-job counts — jobs_search covers live roles, including questions about openings for a particular job title. Each response includes a system_instruction describing how to present the sources.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum articles to return (default 5) | |
| query | Yes | The career, job-search, or FoundRole product question to answer | |
| company | No | A company name, when the question is about that employer — returns FoundRole company profile pages | |
| location | No | A city, state, or country, when the question is about that labour market — returns its market landing page |
Output Schema
| Name | Required | Description |
|---|---|---|
| pages | No | |
| proUrl | No | |
| articles | No | |
| totalCount | No | |
| companyPages | No | |
| landingPages | No | |
| profileSetupUrl | No | |
| system_instruction | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, openWorld=false), so the description's job is added context — and it delivers: empty groups rather than padded off-topic results, closest-match (non-exhaustive) semantics, facet behavior, and a system_instruction included in each response. It does not mention pagination or rate limits, but nothing essential is missing.
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?
Front-loaded with the core operation, then facets, then boundaries with siblings. It is on the long side and some enumeration of site-page types (Pro plan, H1B salary data, AI job search) borders on padding, but nearly every sentence carries routing or behavioral 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?
An output schema exists, and the description correctly refrains from re-explaining return values while still flagging the embedded system_instruction and the empty-group behavior. Combined with clear sibling boundaries and facet disambiguation, an agent has everything needed to select and invoke 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 coverage is 100%, so baseline is 3, but the description adds genuine meaning beyond it: 'company' maps to employer profile pages and 'location' maps to an analytical market landing page, not job listings, plus the disambiguation rule that a company mentioned in passing does not need the facet. That goes past restating schema text.
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 precise verb+resource ('Searches FoundRole's published content by semantic similarity') and enumerates the corpora searched (blog articles, product/site pages, sector landings). It explicitly distinguishes itself from siblings jobs_search and knowledge_topics, so an agent can route without opening any schema.
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?
Names the alternatives and the conditions that select them: 'questions about overall topic coverage are answered by knowledge_topics' and 'It does not search job listings... jobs_search covers live roles'. It also gives a when-not for the optional facets ('a company mentioned only in passing does not need the company facet'). This is explicit when/when-not/alternative guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
knowledge_topicsList career guide topicsARead-onlyIdempotentInspect
Lists what FoundRole's published career-guidance blog covers: every category and the most-used tags, each with its published-article count and url, plus the total number of published articles. This is the factual source for questions about the blog's topics or overall coverage. It takes no parameters and reflects the live published corpus. It does not retrieve articles for a specific question; knowledge_search does that.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| tags | No | |
| categories | No | |
| totalArticles | No | |
| system_instruction | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint=false and destructiveHint=false, so safety is covered. The description adds useful behavioral context beyond that: it takes no parameters, reflects the live published corpus (a freshness guarantee, not a cached snapshot), and enumerates what the response contains (categories, tags, per-item article counts and URLs, plus a total). It stops short of stating pagination or result-size limits, so not a full 5.
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?
Front-loaded with what is returned, then the routing rule, then the no-parameter/freshness note. Every sentence carries information, but the return-value enumeration partially duplicates the output schema, which is mild redundancy rather than waste.
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?
With an output schema present, the description needn't explain return values, yet it still names the resource, the freshness behavior, the absence of parameters, and the sibling handoff. Nothing an agent needs in order to call this 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?
The tool has zero parameters, which establishes a baseline of 4; the description correctly and explicitly confirms 'It takes no parameters', removing any doubt that filtering arguments might exist.
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 (lists) and resource (blog categories, most-used tags, counts, URLs, total article count) and explicitly contrasts with the sibling that does something similar but different: 'It does not retrieve articles for a specific question; knowledge_search does that.' An agent can distinguish it from knowledge_search without opening either schema.
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 both the when ('the factual source for questions about the blog's topics or overall coverage') and the when-not, naming the alternative tool that handles the excluded case (article retrieval for a specific question goes to knowledge_search). Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reminder_deleteDelete a reminderADestructiveInspect
Deletes a reminder from a tracked job.
Input:
tracked_job_id: The tracked job ID —trackedJobs[].idfrom tracker_list output, distinct fromtrackable.idandjob.id(required)
Output: Returns the updated tracked job with reminderAt cleared.
| Name | Required | Description | Default |
|---|---|---|---|
| tracked_job_id | Yes | The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required) |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackedJobs | No | |
| trackerWebUrl | No | |
| subStatusOrder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, so the safety profile is covered. The description adds the specific effect — the reminder is removed and reminderAt is cleared while the tracked job survives — which is genuinely useful context beyond the annotation. It does not mention irreversibility or auth, keeping it short of a 5.
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?
Front-loads the action in one sentence and uses labeled Input/Output blocks that scan quickly. Reasonably tight, though the bolded section scaffolding is slightly heavier than the single-parameter tool needs.
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?
With annotations covering destructiveness and an output schema documenting the returned tracked job, the description supplies the one thing not in structured fields — what specifically gets cleared. Complete enough for a one-parameter destructive tool.
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 description's tracked_job_id text is essentially identical to the schema's, so it adds no new meaning. Baseline 3 applies when the schema does the heavy lifting; the disambiguation from trackable.id/job.id is helpful but already in the schema.
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 ('Deletes a reminder from a tracked job'), scoping it to a job rather than reminders generally. An agent can distinguish it from reminder_set and reminder_list without opening either schema.
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?
Usage is only implied by the sibling set (reminder_set/reminder_list) and the destructive verb; there is no explicit statement of when to use delete versus clearing via tracker_update, nor any prerequisite or caution. Minimum viable routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reminder_listList remindersARead-onlyInspect
Lists tracked jobs that have reminders set, ordered by reminder time (soonest first).
Input:
limit: Number of results to return (default 20, max 50)
Output: Returns a list of tracked jobs with active reminders.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of results to return (default 20, max 50) |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJobs | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, so the safety profile is covered by structured data. The description adds genuine behavioral context not present elsewhere: the soonest-first ordering and the max-50 cap. It does not cover pagination beyond limit, empty-result behavior, or permission requirements, and the Input restatement duplicates the schema rather than adding to it.
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?
Front-loaded one-sentence purpose followed by short Input/Output blocks; nothing is bloated. Minor waste in the Input block, which restates the schema's limit description word-for-word instead of adding 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?
A simple, side-effect-free list tool with a rich output schema (return values need not be explained) and full sibling context. Ordering, scope, and the limit cap are the only things an agent materially needs, and ordering plus scope are present; only the alert-vs-reminder distinction is left to inference.
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?
There is a single parameter with 100% schema description coverage, so the schema already documents default 20 / max 50. The description merely repeats this verbatim rather than adding semantics, which is the expected baseline 3 for a fully covered schema.
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 ('Lists tracked jobs that have reminders set') and adds a scope/ordering qualifier ('ordered by reminder time, soonest first'). An agent can distinguish it from tracker_list, job_alert_list, and reminder_set/delete from the description alone, though it never names those siblings explicitly.
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?
Usage is implied by the purpose (call this to view existing reminders) but there is no explicit when/when-not guidance and no mention of the adjacent alternatives in the sibling list, notably job_alert_list (alerts vs reminders) and tracker_list. Nothing misleading, just under-specified routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reminder_setSet a follow-up reminderADestructiveInspect
Sets a reminder for a tracked job. Sends a confirmation email with .ics calendar attachment.
Input:
tracked_job_id: The tracked job ID —trackedJobs[].idfrom tracker_list output, distinct fromtrackable.idandjob.id(required)remind_at: Reminder date/time in ISO 8601 format, e.g. "2025-03-15T10:00:00Z" (required, must be in the future)
Output: Returns the updated tracked job with reminderAt field.
| Name | Required | Description | Default |
|---|---|---|---|
| remind_at | Yes | ISO 8601 datetime, e.g. "2025-03-15T10:00:00Z" (must be in the future) | |
| tracked_job_id | Yes | The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required) |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackedJobs | No | |
| trackerWebUrl | No | |
| subStatusOrder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations already declaring readOnlyHint=false, destructiveHint=true and openWorldHint=true, the description usefully adds the email/ICS side effect and the return payload (updated tracked job with reminderAt). It does not explain what makes the operation destructive (e.g. overwriting an existing reminder), which is the one gap left against a destructiveHint=true annotation.
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?
Front-loaded with the core action in the first sentence, then clearly sectioned Input/Output blocks. Slightly padded by duplicating schema parameter text verbatim, but every line is scannable and nothing is buried.
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?
An output schema exists, so explaining return values is optional, yet the description summarizes the reminderAt field, which is helpful rather than harmful. Combines with annotation coverage to give an agent everything needed to invoke the tool correctly, minus any note on idempotency/overwrite behavior.
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 both parameters are already fully documented with identical wording (ISO 8601 example, distinct-ID warning). The description restates the schema rather than adding new syntax or constraints, so the baseline of 3 applies.
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 ("Sets a reminder for a tracked job") and adds the concrete side effect of sending a confirmation email with an .ics attachment. This clearly separates it from reminder_list and reminder_delete in the sibling set.
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?
Usage is implied by the title and the note that remind_at must be in the future, but there is no explicit when-to-use/when-not guidance or routing to sibling tools such as reminder_delete or reminder_list. Adequate but leaves the agent to infer context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resume_checkCheck how hiring software reads a resumeARead-onlyIdempotentInspect
Checks resume text for machine-readable sections, recognized skills, contact channels, a headline, and experience date ranges using FoundRole's deterministic parser.
Pass resume_text to check plain text supplied in the conversation. If resume_text is omitted, the tool reads the previously extracted text of the primary resume in the authenticated user's FoundRole account. It returns a readability band (strong, good, partial), parsed facts, and findings. This is FoundRole's text-readability assessment, not a test against a named ATS, a hiring prediction, or a file-layout check. Pasted text does not preserve the original PDF or DOCX layout.
The tool does not upload a file, create a saved resume or report, change the user's profile, submit an application, or fetch URLs found in the text. It may return a FoundRole website link; opening that link and uploading or editing a resume are separate user actions. Operational request records and diagnostics may retain tool inputs; this tool does not promise that submitted text is never stored.
| Name | Required | Description | Default |
|---|---|---|---|
| resume_text | No | Plain text of the resume to check, when it is available in the conversation. Omit to check the resume uploaded to the user's FoundRole account. Minimum 200 characters. |
Output Schema
| Name | Required | Description |
|---|---|---|
| band | No | |
| mode | Yes | |
| findings | No | |
| parsedAs | No | |
| uploadUrl | No | |
| studioReportUrl | No | |
| system_instruction | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, but the description goes well beyond them: no file upload, no saved resume or report, no profile change, no application submission, no URL fetching, plus a candid retention caveat and a note that returned website links require separate user action. That is unusually rich behavioral disclosure for a read tool.
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?
Four short paragraphs, front-loaded with purpose, then input behavior, then scope exclusions, then side-effect disclaimers. Every sentence carries information, though the negative-capability list is somewhat exhaustive and could be tightened slightly.
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?
With an output schema present, return values need not be explained, yet the description still summarizes the readability band and outputs. Combined with the input fallback semantics and full side-effect disclosure, nothing an agent needs to call this 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 description coverage is 100% and the single optional parameter is fully documented there, including the minimum-length constraint. The description restates the pass/omit behavior but adds no syntax, format, or constraint detail beyond the schema, so the baseline of 3 applies.
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 ('checks resume text for machine-readable sections, recognized skills, contact channels, a headline, and experience date ranges') and names the mechanism (FoundRole's deterministic parser). It also explicitly carves out what it is not (ATS test, hiring prediction, file-layout check), so an agent can distinguish it from analysis-adjacent siblings like jobs_analyze_external.
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 an explicit branch: pass resume_text when the text is in the conversation, omit it to use the stored primary resume. It further names exclusions ('not a test against a named ATS, a hiring prediction, or a file-layout check') and notes the layout caveat for pasted text, which routes the agent correctly for edge cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracker_addSave a job to the trackerAInspect
Tracks a job from jobs_search results in the user's job tracker, identified by its job_id. For a job found elsewhere on the open web (with a URL but no jobs_search job_id), tracker_add_external is the right tool instead.
Fields:
job_id: the job ID from jobs_search results (required)status: initial status (saved, applied, interviewing, offered, archived); defaults to "saved"sub_status: sub-status within the main status: saved: interested, researching_company, preparing_application, ready_to_apply; applied: application_submitted, followed_up; interviewing: interview_scheduled, phone_screen, technical, onsite, final_round, pending_feedback; offered: negotiating, considering, offer_received, accepted; archived: ghosted, rejected_by_company, withdrawn_by_candidate, not_interested, employed_by_this_company, employed_by_another_companynotes: notes about the job
Returns the tracked job with its details. Repeated saves return the existing tracked job. A job that was previously removed from the tracker is restored with its earlier status and notes.
| Name | Required | Description | Default |
|---|---|---|---|
| notes | No | Notes about this job | |
| job_id | Yes | The job ID from jobs.search results | |
| status | No | Initial tracking status: saved, applied, interviewing, offered, archived | |
| sub_status | No | Sub-status within the main status, valid only for that status — saved: interested, researching_company, preparing_application, ready_to_apply; applied: application_submitted, followed_up; interviewing: interview_scheduled, phone_screen, technical, onsite, final_round, pending_feedback; offered: negotiating, considering, offer_received, accepted; archived: ghosted, rejected_by_company, withdrawn_by_candidate, not_interested, employed_by_this_company, employed_by_another_company | |
| result_item_id | No | The result occurrence ID returned with the selected job |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackedJobs | No | |
| trackerWebUrl | No | |
| subStatusOrder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=false, destructiveHint=false, openWorldHint=false, so safety is already covered. The description adds genuinely non-obvious behavior beyond the annotations: repeated saves are idempotent ('return the existing tracked job') and a previously removed job is restored with its earlier status and notes. It does not clarify whether a new status/sub_status passed on a repeated save overrides the stored one, which is a minor gap.
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?
Front-loaded with the purpose and the routing rule, then a scannable field list. The main inefficiency is the full sub_status enumeration, which duplicates the schema text verbatim and consumes a large share of the description without adding meaning.
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?
An output schema exists and the description still summarizes the return ('Returns the tracked job with its details'), and the mutation's idempotency/restore behavior is disclosed. What is missing is any steer toward the related mutation siblings (tracker_update, tracker_update_status) that an agent would need when the job already exists.
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, but the description adds the default value for status ('defaults to "saved"'), which the schema does not state. It also omits any mention of result_item_id (present in the schema) and mostly restates the status/sub_status enumerations verbatim.
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 ('Tracks a job from jobs_search results in the user's job tracker, identified by its job_id') and immediately names the sibling it is not (tracker_add_external). An agent can distinguish this from tracker_add_external without opening either schema.
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 gives the routing condition: use tracker_add for jobs with a jobs_search job_id, and use tracker_add_external for jobs found elsewhere with a URL but no job_id. This is a concrete when-to-use-this-vs-alternative statement rather than implied guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracker_add_externalSave a job from another site to the trackerAInspect
Saves a job posting found anywhere on the open web into the user's tracker. For jobs that came from jobs_search results, tracker_add (which takes a job_id) is the right tool instead. A job seen elsewhere in the conversation needs no prior jobs_search call — its URL and details from the conversation are sufficient input.
url, company_name, title_name, location_name, and description identify the posting
and are the only required fields. Every structured fact field (salary, dates, employment type,
education, experience) is optional: a fact the source does not state is simply omitted (or
null), and FoundRole's own extractors derive missing salary, employment, work-arrangement,
education, experience, skills, benefits, and bonuses from the description. A save never waits
on facts the source did not provide. The optional client_extraction object carries
evidence-backed skills, technology, benefits, bonuses, seniority, industry, management,
clearance, visa, and remote-scope labels when source excerpts for them exist; FoundRole
validates and stores those labels separately.
Fields:
url: the job posting's direct URL (required; not a company homepage)company_name: company name (required)title_name: job title (required)location_name: location, e.g. "New York, NY" (required)description: the posting's description from the source result; a short summary is acceptable (required)salary_min_value/salary_max_value: salary range bounds (numbers)salary_value: a single salary figure when there is no range (number)posted_at: ISO 8601 posting datesalary_currency: ISO 4217 currency codesalary_type: one of year, month, week, day, houremployment_type: array of full_time, part_time, contractor, temporary, intern, volunteer, per_diem, otherwork_location_type: one of on_site, remote, hybrideducation_requirements: array of no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degreeexperience_months: minimum required experience in months (number)client_extraction: evidence-backed extraction object; fields without source evidence are omittedstatus: initial tracking status (saved, applied, interviewing, offered, archived); defaults to "saved"sub_status: sub-status within the main status: saved: interested, researching_company, preparing_application, ready_to_apply; applied: application_submitted, followed_up; interviewing: interview_scheduled, phone_screen, technical, onsite, final_round, pending_feedback; offered: negotiating, considering, offer_received, accepted; archived: ghosted, rejected_by_company, withdrawn_by_candidate, not_interested, employed_by_this_company, employed_by_another_companynotes: notes about the job
Returns the tracked job. Repeated saves return the existing tracked job.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Direct URL of the specific job posting; a company homepage is invalid | |
| notes | No | Notes about this job | |
| status | No | Initial tracking status: saved, applied, interviewing, offered, archived | |
| posted_at | No | Posting date as ISO 8601, when the source states it | |
| sub_status | No | Sub-status within the main status, valid only for that status — saved: interested, researching_company, preparing_application, ready_to_apply; applied: application_submitted, followed_up; interviewing: interview_scheduled, phone_screen, technical, onsite, final_round, pending_feedback; offered: negotiating, considering, offer_received, accepted; archived: ghosted, rejected_by_company, withdrawn_by_candidate, not_interested, employed_by_this_company, employed_by_another_company | |
| title_name | Yes | Job title from the posting | |
| description | Yes | Complete posting text available in the conversation; a source summary is valid only when no fuller posting text is available | |
| salary_type | No | Salary period: year, month, week, day, hour | |
| company_name | Yes | Company name from the posting | |
| salary_value | No | Single salary amount, when the posting gives one figure instead of a range | |
| location_name | Yes | Location text from the posting, including Remote when stated | |
| employment_type | No | Employment types: full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other | |
| salary_currency | No | ISO 4217 salary currency code, when stated | |
| salary_max_value | No | Salary range maximum, when stated | |
| salary_min_value | No | Salary range minimum, when stated | |
| client_extraction | No | Evidence-backed facts extracted by the client model from the posting; non-null evidence is a short source excerpt rather than an inference. Fields absent from the source are omitted or null. | |
| experience_months | No | Minimum required experience in months, when stated | |
| work_location_type | No | Work arrangement: on_site, remote, hybrid | |
| education_requirements | No | Education requirements: no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackedJobs | No | |
| trackerWebUrl | No | |
| subStatusOrder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations establish the safety profile (readOnlyHint=false, destructiveHint=false, openWorldHint=false), and the description adds important behavior: repeated saves return the existing tracked job, missing facts are omitted rather than blocking, extractors derive missing structured facts, and client_extraction labels are validated and stored separately. These are non-obvious operational traits that go well beyond the 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?
The opening usage guidance is strong and front-loaded, but the long bulleted enumeration of fields largely duplicates the schema descriptions, including enum values already present in the schema. For a 19-parameter tool some length is warranted, but the redundancy makes it less concise than it could be.
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 complex schema, existing output schema, and annotations, the description covers what an agent needs: required vs optional fields, default status, idempotent repeated saves, derivation of missing facts, and the evidence-backed client_extraction contract. Nothing critical is missing 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 already 100%, so the baseline is 3, but the description adds useful semantics beyond the schema: it identifies the five required identifying fields, states that status defaults to 'saved', and explains that omitted facts are derived by extractors rather than requiring values. The field-by-field list mostly restates schema descriptions, limiting this to a 4.
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 ('Saves a job posting ... into the user's tracker') and explicitly distinguishes itself from the sibling tracker_add by source and input type. An agent can tell when this tool applies without opening the schema.
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 says to use tracker_add instead for jobs that came from jobs_search results, and clarifies that jobs seen elsewhere need no prior jobs_search call. This is precise when-to-use and when-not-to-use guidance tied to a named alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracker_listList tracked jobsARead-onlyInspect
Lists the user's tracked jobs with optional filtering and pagination.
Input:
status: Filter by status (saved, applied, interviewing, offered, archived)limit: Number of results per page (default 20, max 50)offset: Number of results to skip (default 0)
Output: Returns a list of tracked jobs grouped by status with pagination info. Each response includes a system_instruction describing how to present the results for the current client.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Number of results per page (default 20, max 50) | |
| offset | No | Number of results to skip (default 0) | |
| status | No | Filter by status: saved, applied, interviewing, offered, archived |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackedJobs | No | |
| trackerWebUrl | No | |
| subStatusOrder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false. The description goes beyond them by disclosing that results come back grouped by status, that pagination metadata is included, and that a system_instruction governs result presentation for the current client — genuinely useful behavioral context for a read tool.
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?
Front-loaded with the one-line purpose, then clearly sectioned Input/Output headings — easy to scan. It loses a point for duplicating the schema's parameter text verbatim, which is redundancy rather than added 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 simple zero-required-parameter list tool with a full output schema and strong annotations, the description covers purpose, params, and response shape adequately. Nothing critical is missing, though it could note the default ordering of the grouped results.
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 parameters are already fully documented. The Input section restates the schema word-for-word (default 20, max 50, default 0, enum-like status values) without adding syntax, validation, or interaction semantics beyond it, so the baseline 3 applies.
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 and resource ("Lists the user's tracked jobs") plus scope (optional filtering and pagination), so the agent immediately knows the operation. It does not distinguish itself from tracker_remove/tracker_update/tracker_update_status, but the read-only listing intent is unmistakable.
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?
Usage is only implied: an agent can infer this is the tool for browsing tracked jobs with filters. There is no explicit when-to-use statement, no named alternative (e.g. jobs_search for non-tracked jobs), and no exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracker_removeRemove a job from the trackerADestructiveInspect
Removes a job from the user's job tracker.
Input:
tracked_job_id: The tracked job ID —trackedJobs[].idfrom tracker_list output, distinct fromtrackable.idandjob.id(required)
Output: Confirms the job was removed from tracking.
| Name | Required | Description | Default |
|---|---|---|---|
| tracked_job_id | Yes | The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required) |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackedJobs | No | |
| trackerWebUrl | No | |
| subStatusOrder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false, and openWorldHint=false, so the safety profile is covered without the description's help. The description adds only the output confirmation ('Confirms the job was removed') and the ID provenance; it says nothing about reversibility, required auth, or side effects, so it is an adequate but not rich supplement.
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?
Short and front-loaded: the purpose leads, then Input and Output are cleanly sectioned. Slight waste in restating the schema's parameter description word-for-word, but nothing is bloated or meandering.
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 single-parameter destructive tool, the description covers purpose, the one input's provenance, and the confirmation result. With an output schema present it need not explain return values, and annotations carry the destructive semantics, leaving only reversibility/auth unaddressed.
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 baseline is 3. The description's parameter text is a verbatim duplicate of the schema's property description, adding no syntax, format, or provenance information beyond what the schema already provides.
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 ('Removes a job from the user's job tracker'), which is unambiguous and cannot be confused with sibling tracker_add/tracker_update/tracker_list. It even disambiguates the identifier space, noting tracked_job_id is distinct from trackable.id and job.id, which is exactly the kind of precision that separates this from neighboring tools.
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 intent to remove an existing tracked job is implied clearly enough by the name and description, but there is no explicit when-to-use, when-not-to-use, or reference to alternative tools (e.g., how this differs from job_alert_unsubscribe). Guidance is inferable rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracker_updateUpdate a tracked jobBDestructiveInspect
Updates details of a tracked job (notes, deadline, salary, tags).
Input:
tracked_job_id: The tracked job ID —trackedJobs[].idfrom tracker_list output, distinct fromtrackable.idandjob.id(required)notes: Updated notesdeadline: Deadline date (ISO 8601 format)salary_offered: Salary amountsalary_offered_type: Salary type: year, month, week, day, hourtags: Comma-separated tags (e.g., "remote,startup,tech")reminder_at: Reminder date/time in ISO 8601 format, e.g. "2025-03-15T10:00:00Z" (must be in the future, or empty to clear)
Output: Returns the updated tracked job.
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Comma-separated tags (e.g., "remote,startup,tech") | |
| notes | No | Notes about this job | |
| deadline | No | Deadline date in ISO 8601 format | |
| reminder_at | No | ISO 8601 datetime, e.g. "2025-03-15T10:00:00Z" (must be in the future, or empty to clear) | |
| salary_offered | No | Salary amount | |
| tracked_job_id | Yes | The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required) | |
| salary_offered_type | No | Salary type: year, month, week, day, hour |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackedJobs | No | |
| trackerWebUrl | No | |
| subStatusOrder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false, so the safety profile is covered. The description adds genuinely useful context (reminder_at must be future or empty to clear; tracked_job_id differs from trackable.id/job.id), but it never states whether omitted fields are preserved or whether the update is reversible/partial.
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?
Front-loads the one-sentence purpose, then organizes parameter and output notes under clear Input/Output headers. Slight redundancy with the schema, but no wasted sentences.
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?
With an output schema present, return values needn't be explained, and the required ID and delta semantics are covered. What is missing is the effect of a destructive/partial update on unmentioned fields, which an agent would want before calling a destructiveHint=true tool.
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 schema already documents every parameter; the description largely restates it, including the reminder_at future constraint and the ID disambiguation. Baseline 3 is correct when the structured schema does 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 first sentence states a specific verb (Updates) and resource (tracked job details) and enumerates the affected fields (notes, deadline, salary, tags). It implicitly distinguishes itself from tracker_update_status by enumerating detail fields, but never names that sibling to make the boundary explicit.
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?
Usage is implied: the field enumeration makes clear this is for non-status details, which separates it from tracker_update_status. However, there is no explicit when-to-use guidance, no named alternative, and no statements about prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracker_update_statusMove a tracked job to another stageBDestructiveInspect
Updates the status of a tracked job.
Input:
tracked_job_id: The tracked job ID —trackedJobs[].idfrom tracker_list output, distinct fromtrackable.idandjob.id(required)status: New status: saved, applied, interviewing, offered, archived (required)sub_status: Sub-status within the main status, valid only for that status (optional): saved: interested, researching_company, preparing_application, ready_to_apply; applied: application_submitted, followed_up; interviewing: interview_scheduled, phone_screen, technical, onsite, final_round, pending_feedback; offered: negotiating, considering, offer_received, accepted; archived: ghosted, rejected_by_company, withdrawn_by_candidate, not_interested, employed_by_this_company, employed_by_another_company
Output: Returns the updated tracked job.
| Name | Required | Description | Default |
|---|---|---|---|
| status | Yes | New status: saved, applied, interviewing, offered, archived | |
| sub_status | No | Sub-status within the main status, valid only for that status — saved: interested, researching_company, preparing_application, ready_to_apply; applied: application_submitted, followed_up; interviewing: interview_scheduled, phone_screen, technical, onsite, final_round, pending_feedback; offered: negotiating, considering, offer_received, accepted; archived: ghosted, rejected_by_company, withdrawn_by_candidate, not_interested, employed_by_this_company, employed_by_another_company | |
| tracked_job_id | Yes | The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required) |
Output Schema
| Name | Required | Description |
|---|---|---|
| hasMore | No | |
| totalCount | No | |
| trackedJob | No | |
| statusOrder | No | |
| trackedJobs | No | |
| trackerWebUrl | No | |
| subStatusOrder | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=true and openWorldHint=false, so the safety profile is covered. The description adds the meaningful behavioral constraint that sub_status is only valid within its parent status, but says nothing about auth requirements, reversibility of a stage change, or side effects such as notifying the employer or altering timestamps.
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 Input/Output structure is front-loaded and easy to scan, but the entire Input block duplicates schema descriptions that are already 100% covered, and the long inline sub_status enumeration is repeated twice across description and schema. Roughly half the text does not earn additional value.
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?
With an output schema present and rich annotations, the description covers the inputs, the valid value space, and the return shape, which is sufficient for correct invocation. It falls short only on sibling differentiation and on what a status transition actually changes on the tracked job.
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 description's Input section reproduces the schema text nearly verbatim, including the full status/sub_status enumerations. It adds no format, defaulting, or interaction semantics beyond what the schema already documents, so the baseline 3 applies.
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 and resource — updating the status of a tracked job — and the title frames it as moving a job between stages. It is clearly a mutation on a tracked job, but it never distinguishes itself from the sibling tracker_update, which an agent would plausibly consider for the same goal.
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?
There is no statement of when to use this tool versus tracker_update or the other tracker_* siblings, nor any prerequisites (e.g., that the job must already be tracked). The only routing hint is that tracked_job_id comes from tracker_list output, which is identification, not usage guidance.
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.
8 tool updates
v1.1.16- Changed
jobs_analyze_external4 fields changed- removed
Output schema / properties / jobs / items / properties / estimatedSalary / properties / basedOnRemoved value: -{ - "type": [ - "string", - "null" - ] -} - added
Output schema / properties / jobs / items / properties / estimatedSalary / properties / currencyAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / studioUrlAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / system_instructionAdded value: +{ + "type": [ + "string", + "null" + ] +}
- Changed
jobs_compare4 fields changed- removed
Output schema / properties / jobs / items / properties / estimatedSalary / properties / basedOnRemoved value: -{ - "type": [ - "string", - "null" - ] -} - added
Output schema / properties / jobs / items / properties / estimatedSalary / properties / currencyAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / studioUrlAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / system_instructionAdded value: +{ + "type": [ + "string", + "null" + ] +}
- Changed
jobs_details6 fields changed- added
Input schema / properties / result_item_idAdded value: +{ + "description": "The result occurrence ID returned with the selected job", + "type": "string" +} - removed
Output schema / properties / job / properties / estimatedSalary / properties / basedOnRemoved value: -{ - "type": [ - "string", - "null" - ] -} - added
Output schema / properties / job / properties / estimatedSalary / properties / currencyAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / job / properties / remoteCheckAdded value: +{ + "properties": { + "quotes": { + "items": { + "properties": { + "source": { + "type": "string" + }, + "text": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "workFrom": { + "properties": { + "allowedPlaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "excludedPlaces": { + "items": { + "type": "string" + }, + "type": "array" + }, + "quotes": { + "items": { + "properties": { + "source": { + "type": "string" + }, + "text": { + "type": [ + "string", + "null" + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "scope": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / job / properties / resultItemIdAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / studioUrlAdded value: +{ + "type": [ + "string", + "null" + ] +}
- Changed
jobs_recommendations30 fields changed- added
Input schema / properties / benefitsAdded value: +{ + "description": "Advanced filter: benefit names such as \"health insurance\", \"401k\" or \"parental leave\"; a job qualifies only when it states every listed benefit. Names that match no known benefit are ignored.", + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" +} - added
Input schema / properties / bonuses_onlyAdded value: +{ + "description": "Advanced filter: only jobs that state a bonus (sign-on, performance, referral, commission and the like).", + "type": "boolean" +} - added
Input schema / properties / companiesAdded value: +{ + "description": "Filter: official company names; a job from any of them qualifies, across every job board each employer posts on. More than one company makes it an advanced filter. Next to company, a job has to match both; hiring_brand narrows company only.", + "items": { + "type": "string" + }, + "maxItems": 20, + "type": "array" +} - added
Input schema / properties / companyAdded value: +{ + "description": "The official company name", + "type": "string" +} - added
Input schema / properties / confirmed_work_fromAdded value: +{ + "description": "Advanced filter: with strict_remote, also leaves out postings that do not say where the work can be done from.", + "type": "boolean" +} - added
Input schema / properties / educationAdded value: +{ + "description": "Filter: jobs whose posting requires one of these education levels (no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree); bachelor_degree means the posting asks for a bachelor degree, not that it suits someone holding one.", + "items": { + "enum": [ + "no_requirements", + "high_school", + "associate_degree", + "bachelor_degree", + "professional_certificate", + "postgraduate_degree" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / employment_typesAdded value: +{ + "description": "Filter: jobs offered as any of these employment types (full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other).", + "items": { + "enum": [ + "full_time", + "part_time", + "contractor", + "temporary", + "intern", + "volunteer", + "per_diem", + "other" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / exclude_companiesAdded value: +{ + "description": "Advanced filter: official company names whose jobs are removed from the results, across every job board each employer posts on.", + "items": { + "type": "string" + }, + "maxItems": 20, + "type": "array" +} - added
Input schema / properties / experience_levelsAdded value: +{ + "description": "Filter: jobs at any of these experience levels (entry_level, mid_level, senior_level, executive). The level comes from the years of experience the posting asks for and the seniority in its title, the higher of the two; entry_level never includes a posting asking for more than two years.", + "items": { + "enum": [ + "entry_level", + "mid_level", + "senior_level", + "executive" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / h1b_sponsors_onlyAdded value: +{ + "description": "Advanced filter: only companies known to sponsor H1B visas.", + "type": "boolean" +} - added
Input schema / properties / hide_low_qualityAdded value: +{ + "description": "Advanced filter: hides postings with a risky ghost grade (D/F); ungraded postings stay.", + "type": "boolean" +} - added
Input schema / properties / hiring_brandAdded value: +{ + "description": "Filter: one brand inside the company, for example company \"Google\" with hiring_brand \"YouTube\"; used only together with company.", + "type": "string" +} - changed
Input schema / properties / location / descriptionPrevious value: -"Optional preferred location name or slug"New value: +"Geographic location (e.g., 'Boston, MA')" - added
Input schema / properties / min_matchAdded value: +{ + "description": "Advanced filter: lowest personal FoundRole match grade to keep, the same letter each job shows in insights.match.grade. A and A- are rare even for a strong resume; B keeps good and strong matches; C+ also keeps fair ones. Needs a resume on the account.", + "enum": [ + "A", + "A-", + "B+", + "B", + "B-", + "C+", + "C" + ], + "type": "string" +} - added
Input schema / properties / posted_days_agoAdded value: +{ + "description": "Number of days ago to search for jobs (1-365)", + "maximum": 365, + "minimum": 1, + "type": "integer" +} - added
Input schema / properties / queryAdded value: +{ + "description": "The full job title or skill (e.g., \"Ruby Developer\", NOT just \"Ruby\")", + "type": "string" +} - added
Input schema / properties / radiusAdded value: +{ + "description": "Search radius in miles around a city location (default 40); not used for state, country or remote searches.", + "maximum": 100, + "minimum": 5, + "type": "integer" +} - added
Input schema / properties / remoteAdded value: +{ + "description": "Advanced filter: only remote-eligible jobs, matched across the whole country of the requested location rather than its radius.", + "type": "boolean" +} - added
Input schema / properties / salary_floorAdded value: +{ + "description": "Advanced filter: minimum annualized salary in USD; a posting qualifies when the lower bound of its pay band reaches the floor. Jobs without a USD salary are dropped.", + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / sortAdded value: +{ + "description": "Result order (score, posted_at, match, salary): score is relevance and the default, posted_at is newest first, salary is highest pay first, match is best personal fit first and needs a resume. Ordering by salary or match is an advanced option.", + "enum": [ + "score", + "posted_at", + "match", + "salary" + ], + "type": "string" +} - added
Input schema / properties / strict_remoteAdded value: +{ + "description": "Advanced filter: only postings checked as fully remote that can be worked from the requested location: the posting names that area, allows anywhere, or does not say where. Stricter than remote; work_modes other than remote do not apply with it.", + "type": "boolean" +} - added
Input schema / properties / work_modesAdded value: +{ + "description": "Advanced filter: jobs in any of these work modes (on_site, remote, hybrid). remote is matched across the whole country of the location, the others within the radius. [\"remote\"] is the same search as remote: true.", + "items": { + "enum": [ + "on_site", + "remote", + "hybrid" + ], + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / continueUrlAdded value: +{ + "type": "string" +} - removed
Output schema / properties / jobs / items / properties / estimatedSalary / properties / basedOnRemoved value: -{ - "type": [ - "string", - "null" - ] -} - added
Output schema / properties / jobs / items / properties / estimatedSalary / properties / currencyAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / jobs / items / properties / relatedAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / jobs / items / properties / resultItemIdAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / previewAdded value: +{ + "properties": { + "continueUrl": { + "type": [ + "string", + "null" + ] + }, + "hidden": { + "type": "integer" + }, + "hiddenAtLeast": { + "type": "boolean" + }, + "shown": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] +} - added
Output schema / properties / resultBatchIdAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / resultSetIdAdded value: +{ + "type": [ + "string", + "null" + ] +}
- Changed
jobs_search30 fields changed- added
Input schema / properties / benefitsAdded value: +{ + "description": "Advanced filter: benefit names such as \"health insurance\", \"401k\" or \"parental leave\"; a job qualifies only when it states every listed benefit. Names that match no known benefit are ignored.", + "items": { + "type": "string" + }, + "maxItems": 10, + "type": "array" +} - added
Input schema / properties / bonuses_onlyAdded value: +{ + "description": "Advanced filter: only jobs that state a bonus (sign-on, performance, referral, commission and the like).", + "type": "boolean" +} - added
Input schema / properties / companiesAdded value: +{ + "description": "Filter: official company names; a job from any of them qualifies, across every job board each employer posts on. More than one company makes it an advanced filter. Next to company, a job has to match both; hiring_brand narrows company only.", + "items": { + "type": "string" + }, + "maxItems": 20, + "type": "array" +} - added
Input schema / properties / confirmed_work_fromAdded value: +{ + "description": "Advanced filter: with strict_remote, also leaves out postings that do not say where the work can be done from.", + "type": "boolean" +} - added
Input schema / properties / educationAdded value: +{ + "description": "Filter: jobs whose posting requires one of these education levels (no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree); bachelor_degree means the posting asks for a bachelor degree, not that it suits someone holding one.", + "items": { + "enum": [ + "no_requirements", + "high_school", + "associate_degree", + "bachelor_degree", + "professional_certificate", + "postgraduate_degree" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / employment_typesAdded value: +{ + "description": "Filter: jobs offered as any of these employment types (full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other).", + "items": { + "enum": [ + "full_time", + "part_time", + "contractor", + "temporary", + "intern", + "volunteer", + "per_diem", + "other" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / exclude_companiesAdded value: +{ + "description": "Advanced filter: official company names whose jobs are removed from the results, across every job board each employer posts on.", + "items": { + "type": "string" + }, + "maxItems": 20, + "type": "array" +} - added
Input schema / properties / experience_levelsAdded value: +{ + "description": "Filter: jobs at any of these experience levels (entry_level, mid_level, senior_level, executive). The level comes from the years of experience the posting asks for and the seniority in its title, the higher of the two; entry_level never includes a posting asking for more than two years.", + "items": { + "enum": [ + "entry_level", + "mid_level", + "senior_level", + "executive" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / hiring_brandAdded value: +{ + "description": "Filter: one brand inside the company, for example company \"Google\" with hiring_brand \"YouTube\"; used only together with company.", + "type": "string" +} - changed
Input schema / properties / min_match / descriptionPrevious value: -"Advanced filter: minimum personal FoundRole match score (0-100); needs a resume on the account."New value: +"Advanced filter: lowest personal FoundRole match grade to keep, the same letter each job shows in insights.match.grade. A and A- are rare even for a strong resume; B keeps good and strong matches; C+ also keeps fair ones. Needs a resume on the account." - added
Input schema / properties / min_match / enumAdded value: +[ + "A", + "A-", + "B+", + "B", + "B-", + "C+", + "C" +] - removed
Input schema / properties / min_match / maximumRemoved value: -100 - removed
Input schema / properties / min_match / minimumRemoved value: -0 - changed
Input schema / properties / min_match / typePrevious value: -"integer"New value: +"string" - added
Input schema / properties / radiusAdded value: +{ + "description": "Search radius in miles around a city location (default 40); not used for state, country or remote searches.", + "maximum": 100, + "minimum": 5, + "type": "integer" +} - changed
Input schema / properties / remote / descriptionPrevious value: -"Advanced filter: only remote-eligible jobs (respects the location/region scope)."New value: +"Advanced filter: only remote-eligible jobs, matched across the whole country of the requested location rather than its radius." - changed
Input schema / properties / salary_floor / descriptionPrevious value: -"Advanced filter: minimum annualized salary in USD; a posting qualifies when the midpoint of its pay band reaches the floor. Jobs without salary data are dropped."New value: +"Advanced filter: minimum annualized salary in USD; a posting qualifies when the lower bound of its pay band reaches the floor. Jobs without a USD salary are dropped." - added
Input schema / properties / sortAdded value: +{ + "description": "Result order (score, posted_at, match, salary): score is relevance and the default, posted_at is newest first, salary is highest pay first, match is best personal fit first and needs a resume. Ordering by salary or match is an advanced option.", + "enum": [ + "score", + "posted_at", + "match", + "salary" + ], + "type": "string" +} - added
Input schema / properties / strict_remoteAdded value: +{ + "description": "Advanced filter: only postings checked as fully remote that can be worked from the requested location: the posting names that area, allows anywhere, or does not say where. Stricter than remote; work_modes other than remote do not apply with it.", + "type": "boolean" +} - added
Input schema / properties / work_modesAdded value: +{ + "description": "Advanced filter: jobs in any of these work modes (on_site, remote, hybrid). remote is matched across the whole country of the location, the others within the radius. [\"remote\"] is the same search as remote: true.", + "items": { + "enum": [ + "on_site", + "remote", + "hybrid" + ], + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / continueUrlAdded value: +{ + "type": "string" +} - removed
Output schema / properties / jobs / items / properties / estimatedSalary / properties / basedOnRemoved value: -{ - "type": [ - "string", - "null" - ] -} - added
Output schema / properties / jobs / items / properties / estimatedSalary / properties / currencyAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / jobs / items / properties / relatedAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / jobs / items / properties / resultItemIdAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / previewAdded value: +{ + "properties": { + "continueUrl": { + "type": [ + "string", + "null" + ] + }, + "hidden": { + "type": "integer" + }, + "hiddenAtLeast": { + "type": "boolean" + }, + "shown": { + "type": "integer" + } + }, + "type": [ + "object", + "null" + ] +} - removed
Output schema / properties / proFilterUpsellUrlRemoved value: -{ - "type": [ - "string", - "null" - ] -} - added
Output schema / properties / resultBatchIdAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / resultSetIdAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / system_instructionAdded value: +{ + "type": "string" +}
- Changed
knowledge_search4 fields changed- removed
Input schema / properties / job_titleRemoved value: -{ - "description": "A job title or role, when the question is about openings for it — returns job-listing landing pages", - "type": "string" -} - changed
Input schema / properties / location / descriptionPrevious value: -"A city, state, or country refining job_title, or alone when the question is about jobs in that place"New value: +"A city, state, or country, when the question is about that labour market — returns its market landing page" - removed
Output schema / properties / companyPages / items / properties / openJobsRemoved value: -{ - "type": [ - "integer", - "null" - ] -} - removed
Output schema / properties / landingPages / items / properties / openJobsRemoved value: -{ - "type": [ - "integer", - "null" - ] -}
- Added
resume_check - Changed
tracker_add1 field changed- added
Input schema / properties / result_item_idAdded value: +{ + "description": "The result occurrence ID returned with the selected job", + "type": "string" +}
20 tool updates
v1.1.9- First observed
job_alert_list - First observed
job_alert_subscribe - First observed
job_alert_unsubscribe - First observed
job_alert_unsubscribe_all - First observed
jobs_analyze_external - First observed
jobs_compare - First observed
jobs_details - First observed
jobs_recommendations - First observed
jobs_search - First observed
knowledge_search - First observed
knowledge_topics - First observed
reminder_delete - First observed
reminder_list - First observed
reminder_set - First observed
tracker_add - First observed
tracker_add_external - First observed
tracker_list - First observed
tracker_remove - First observed
tracker_update - First observed
tracker_update_status
TDQS
Scored across 21 tools
Most tools target clearly distinct resources and actions (alerts vs tracker vs reminders vs knowledge vs resume). A few boundaries blur: jobs_search and jobs_recommendations both return job feeds, and reminder_set overlaps with tracker_update's reminder_at field, but the descriptions do clarify intent.
Tools follow a mostly predictable domain_verb pattern (job_alert_subscribe, tracker_add, knowledge_search, resume_check). Minor deviations exist, notably the plural 'jobs_' prefix versus singular 'job_alert_' and the 'external' suffix variants, but the scheme is readable throughout.
21 tools is on the heavy side for what is a fairly broad domain with multiple sub-areas (jobs, alerts, tracker, reminders, knowledge, resume). Every tool arguably earns its place, but the surface borders on being too large and could be consolidated.
The surface covers the full lifecycle across its sub-domains: search/details/compare/analyze for jobs, subscribe/list/unsubscribe for alerts, add/list/update/remove for tracking, and set/list/delete for reminders. Gaps are minor, such as the deliberate exclusion of resume upload or profile editing.
Maintenance
Related MCP Connectors
Manage job applications — jobs, companies, boards, notes, and profile — from your AI client.
Job platform for AI agents. Track tech jobs from companies that match your stack.
Analyze job listings against your resume, track applications, and generate cover letters.
Search AI-native jobs, inspect application forms, and fetch free interview-prep resources.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to pull live job listings from major ATS platforms (Greenhouse, Lever, Ashby, Workable), Hacker News hiring threads, and detect hiring signals on company career pages.-
- AlicenseAqualityCmaintenanceAn MCP server for searching UK tech jobs from the winterchill catalog, enabling job search, company lookup, and CV matching/tailoring via LLM agents.6MIT
- AlicenseNot gradedqualityBmaintenanceEnables natural-language job search and aggregation from multiple recruitment websites with zero configuration, providing filtered results and standardized output for AI assistants.37 npmISC
- AlicenseAqualityBmaintenanceEnables AI agents to search job openings across free sources, prepare application materials using known experience, and handle authorized email sending and follow-ups.92MIT