# FoundRole — AI Job Search & Application Tracker MCP for Claude & ChatGPT (remote · www.foundrole.com)

MCP server for AI job search — find jobs, track applications, get alerts. Claude, ChatGPT, Cursor.

- Trust score: 79/100 (medium)
- Change this week: +6
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- remote · `www.foundrole.com`: 79/100 (this document), [markdown](https://verifymcp.io/servers/foundrole-jobs-mcp-proxy/www.md), [page](https://verifymcp.io/servers/foundrole-jobs-mcp-proxy/www)
- npm · `@foundrole/ai-job-search-mcp`: 34/100, [markdown](https://verifymcp.io/servers/foundrole-jobs-mcp-proxy/foundrole-ai-job-search-mcp.md), [page](https://verifymcp.io/servers/foundrole-jobs-mcp-proxy/foundrole-ai-job-search-mcp)

## Channel facts

- Endpoint: `https://www.foundrole.com/mcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `1.1.9`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Endpoint Security**: 94/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation is enforced on tool calls, advertised via RFC 9728 protected-resource metadata. Discovery is public, which costs nothing: no tool can be invoked without a token.
  - HTTPS is enforced; there's no plaintext access path.
  - The HSTS (Strict-Transport-Security) header is present.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
  - The authorisation server offers only Dynamic Client Registration (RFC 7591), which MCP 2026-07-28 deprecated in favour of Client ID Metadata Documents.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 75/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 6208 tokens (~310/item across 20 items; 20 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 6/100
  - Stability check failed: schema churn in the 8 days we've observed: 4 tool removals, 0 breaking changes, 0 auth/transport breaks, 4 additions.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add --transport http foundrole-jobs-mcp-proxy https://www.foundrole.com/mcp
```

### Codex

```toml
[mcp_servers.foundrole-jobs-mcp-proxy]
url = "https://www.foundrole.com/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "foundrole-jobs-mcp-proxy": {
      "type": "remote",
      "url": "https://www.foundrole.com/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add foundrole-jobs-mcp-proxy --url https://www.foundrole.com/mcp --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  foundrole-jobs-mcp-proxy:
    url: "https://www.foundrole.com/mcp"
```

### Other

```json
{
  "mcpServers": {
    "foundrole-jobs-mcp-proxy": {
      "type": "http",
      "url": "https://www.foundrole.com/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-03 (score 79, +1)

No change was recorded against any check on this day. Stability & Change Management went from 3 to 6.

### 2026-07-31 (score 78, +5)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-27 (score 73, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-26 (score 73)

First indexed and scored.

## MCP tools (20)

### `job_alert_unsubscribe` (~140 tokens)

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 by `jobs_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.

Input parameters:

- `job_search_id` (string, required): Job search UUID or composite job id ("seo_id--job_search_id") from jobs_search results

Output parameters:

- `message` (string)
- `success` (boolean)

### `job_alert_subscribe` (~192 tokens)

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 by `jobs_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.

Input parameters:

- `frequency` (string): Alert frequency: daily, weekly, monthly (defaults to "weekly")
- `job_search_id` (string, required): Job search UUID or composite job id ("seo_id--job_search_id") from jobs_search results

Output parameters:

- `jobAlert` (object)

### `job_alert_list` (~188 tokens)

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.

Input parameters:

- `limit` (integer): Number of results to return (default 20, max 50)
- `offset` (integer): Number of results to skip (default 0)
- `status` (string): Filter by status: pending, active, unsubscribed

Output parameters:

- `frequencies` (array)
- `hasMore` (boolean)
- `jobAlerts` (array)
- `totalCount` (integer)

### `job_alert_unsubscribe_all` (~128 tokens)

Unsubscribes the authenticated user from ALL of their job alerts at once, across every
subscription source (regular, company page, MCP).

\**Input:**
\- `confirm`: Must be `true` to 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.

Input parameters:

- `confirm` (boolean, required): Set to true to confirm unsubscribing from every alert; the call is rejected otherwise

Output parameters:

- `message` (string)
- `success` (boolean)

### `jobs_analyze_external` (~598 tokens)

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.

Input parameters:

- `client_extraction` (object|null): 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.
- `company_name` (string, required): Company name from the posting
- `description` (string, required): Complete posting text available in the conversation; a source summary is valid only when no fuller posting text is available
- `education_requirements` (array|null): Education requirements: no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree
- `employment_type` (array|null): Employment types: full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other
- `experience_months` (integer|null): Minimum required experience in months, when stated
- `location_name` (string, required): Location text from the posting, including Remote when stated
- `posted_at` (string|null): Posting date as ISO 8601, when the source states it
- `salary_currency` (string|null): ISO 4217 salary currency code, when stated
- `salary_max_value` (number|null): Salary range maximum, when stated
- `salary_min_value` (number|null): Salary range minimum, when stated
- `salary_type` (string|null): Salary period: year, month, week, day, hour
- `salary_value` (number|null): Single salary amount, when the posting gives one figure instead of a range
- `title_name` (string, required): Job title from the posting
- `url` (string, required): Direct URL of the specific job posting; a company homepage is invalid
- `work_location_type` (string|null): Work arrangement: on_site, remote, hybrid

Output parameters:

- `clientExtraction` (object|null)
- `derivedFields` (array)
- `jobs` (array)
- `mode` (string)
- `providedFields` (array)
- `statusOrder` (array)
- `trackerWebUrl` (string)
- `unknownFields` (array)

### `jobs_compare` (~152 tokens)

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.

Input parameters:

- `comparison_refs` (array, required): Two to four exact FoundRole job IDs or external comparisonRef URLs

Output parameters:

- `jobs` (array)
- `mode` (string)
- `statusOrder` (array)
- `trackerWebUrl` (string)

### `jobs_details` (~134 tokens)

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 the `id` field of a `jobs_search` result.

\**Output:**
Complete job details: description, skills, benefits, requirements, salary benchmark, resume match,
H-1B and E-Verify signals, job-trust analysis, and application link. Personalized and extended
insight fields follow the authenticated user's current entitlements.

Input parameters:

- `job_id` (string, required): The unique identifier of the job from jobs_search results

Output parameters:

- `job` (object)
- `statusOrder` (array)
- `trackedJob` (object|null)
- `trackerWebUrl` (string)

### `jobs_recommendations` (~121 tokens)

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.

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.

Input parameters:

- `location` (string): Optional preferred location name or slug
- `page` (integer): Recommendation page number

Output parameters:

- `feedKind` (string)
- `feedStatus` (string)
- `jobSearchId` (string|null)
- `jobs` (array)
- `nextPage` (integer|null)
- `profileSetupState` (string|null)
- `profileSetupUrl` (string|null)
- `revalidating` (boolean)
- `statusOrder` (array)
- `totalCount` (integer)
- `trackerWebUrl` (string)

### `jobs_search` (~552 tokens)

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`; jobs_details takes that `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.

Authenticated results include resume match data when a profile is available. 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.

Advanced constraints in the user's request — remote-only work, H1B sponsorship, a minimum salary,
hiding risky postings, a minimum match score — are the search parameters remote, h1b_sponsors_only,
salary_floor, hide_low_quality, and min_match. The search enforces only constraints passed as
parameters; a constraint left out of the call is not applied to the result set. FoundRole Pro
accounts receive the screened list; other accounts receive the full list and the response reports
that the advanced filters were not applied.

Each response includes a system_instruction describing how to present the results for the current
client.

Input parameters:

- `company` (string): The official company name
- `cursor` (string): Pagination cursor. Treat as an opaque string. COPY EXACTLY.
- `h1b_sponsors_only` (boolean): Advanced filter: only companies known to sponsor H1B visas.
- `hide_low_quality` (boolean): Advanced filter: hides postings with a risky ghost grade (D/F); ungraded postings stay.
- `location` (string): Geographic location (e.g., 'Boston, MA')
- `min_match` (integer): Advanced filter: minimum personal FoundRole match score (0-100); needs a resume on the account.
- `posted_days_ago` (integer): Number of days ago to search for jobs (1-365)
- `query` (string): The full job title or skill (e.g., "Ruby Developer", NOT just "Ruby")
- `remote` (boolean): Advanced filter: only remote-eligible jobs (respects the location/region scope).
- `salary_floor` (integer): 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.

Output parameters:

- `feedKind` (string)
- `feedStatus` (string|null)
- `jobSearchId` (string|null)
- `jobs` (array)
- `lowRelevanceNotice` (string|null)
- `proFilterUpsellUrl` (string|null)
- `profileSetupState` (string|null)
- `profileSetupUrl` (string|null)
- `revalidating` (boolean)
- `statusOrder` (array)
- `trackerWebUrl` (string)

### `knowledge_search` (~398 tokens)

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.

Three optional facets add further result groups: company returns FoundRole's employer profile pages
matching that company name; job_title and location return the live job-listing landing pages for that
role and place, with open-job counts. 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; jobs_search covers live roles. Each response includes a
system_instruction describing how to present the sources.

Input parameters:

- `company` (string): A company name, when the question is about that employer — returns FoundRole company profile pages
- `job_title` (string): A job title or role, when the question is about openings for it — returns job-listing landing pages
- `limit` (integer): Maximum articles to return (default 5)
- `location` (string): A city, state, or country refining job_title, or alone when the question is about jobs in that place
- `query` (string, required): The career, job-search, or FoundRole product question to answer

Output parameters:

- `articles` (array)
- `companyPages` (array)
- `landingPages` (array)
- `pages` (array)
- `proUrl` (string|null)
- `profileSetupUrl` (string|null)
- `system_instruction` (string)
- `totalCount` (integer)

### `knowledge_topics` (~92 tokens)

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.

Output parameters:

- `categories` (array)
- `system_instruction` (string)
- `tags` (array)
- `totalArticles` (integer)

### `reminder_delete` (~110 tokens)

Deletes a reminder from a tracked job.

\**Input:**
\- `tracked_job_id`: The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required)

\**Output:**
Returns the updated tracked job with reminderAt cleared.

Input parameters:

- `tracked_job_id` (string, required): The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required)

Output parameters:

- `hasMore` (boolean)
- `statusOrder` (array)
- `subStatusOrder` (object)
- `totalCount` (integer)
- `trackedJob` (object)
- `trackedJobs` (array)
- `trackerWebUrl` (string)

### `reminder_list` (~81 tokens)

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.

Input parameters:

- `limit` (integer): Number of results to return (default 20, max 50)

Output parameters:

- `hasMore` (boolean)
- `totalCount` (integer)
- `trackedJobs` (array)

### `reminder_set` (~201 tokens)

Sets a reminder for a tracked job. Sends a confirmation email with .ics calendar attachment.

\**Input:**
\- `tracked_job_id`: The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.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.

Input parameters:

- `remind_at` (string, required): ISO 8601 datetime, e.g. "2025-03-15T10:00:00Z" (must be in the future)
- `tracked_job_id` (string, required): The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required)

Output parameters:

- `hasMore` (boolean)
- `statusOrder` (array)
- `subStatusOrder` (object)
- `totalCount` (integer)
- `trackedJob` (object)
- `trackedJobs` (array)
- `trackerWebUrl` (string)

### `tracker_list` (~164 tokens)

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.

Input parameters:

- `limit` (integer): Number of results per page (default 20, max 50)
- `offset` (integer): Number of results to skip (default 0)
- `status` (string): Filter by status: saved, applied, interviewing, offered, archived

Output parameters:

- `hasMore` (boolean)
- `statusOrder` (array)
- `subStatusOrder` (object)
- `totalCount` (integer)
- `trackedJob` (object)
- `trackedJobs` (array)
- `trackerWebUrl` (string)

### `tracker_remove` (~110 tokens)

Removes a job from the user's job tracker.

\**Input:**
\- `tracked_job_id`: The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required)

\**Output:**
Confirms the job was removed from tracking.

Input parameters:

- `tracked_job_id` (string, required): The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required)

Output parameters:

- `hasMore` (boolean)
- `statusOrder` (array)
- `subStatusOrder` (object)
- `totalCount` (integer)
- `trackedJob` (object)
- `trackedJobs` (array)
- `trackerWebUrl` (string)

### `tracker_add_external` (~1120 tokens)

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 date
\- `salary_currency`: ISO 4217 currency code
\- `salary_type`: one of year, month, week, day, hour
\- `employment_type`: array of full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other
\- `work_location_type`: one of on_site, remote, hybrid
\- `education_requirements`: array of no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, pos…

Input parameters:

- `client_extraction` (object|null): 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.
- `company_name` (string, required): Company name from the posting
- `description` (string, required): Complete posting text available in the conversation; a source summary is valid only when no fuller posting text is available
- `education_requirements` (array|null): Education requirements: no_requirements, high_school, associate_degree, bachelor_degree, professional_certificate, postgraduate_degree
- `employment_type` (array|null): Employment types: full_time, part_time, contractor, temporary, intern, volunteer, per_diem, other
- `experience_months` (integer|null): Minimum required experience in months, when stated
- `location_name` (string, required): Location text from the posting, including Remote when stated
- `notes` (string): Notes about this job
- `posted_at` (string|null): Posting date as ISO 8601, when the source states it
- `salary_currency` (string|null): ISO 4217 salary currency code, when stated
- `salary_max_value` (number|null): Salary range maximum, when stated
- `salary_min_value` (number|null): Salary range minimum, when stated
- `salary_type` (string|null): Salary period: year, month, week, day, hour
- `salary_value` (number|null): Single salary amount, when the posting gives one figure instead of a range
- `status` (string): Initial tracking status: saved, applied, interviewing, offered, archived
- `sub_status` (string): 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; interviewin…
- `title_name` (string, required): Job title from the posting
- `url` (string, required): Direct URL of the specific job posting; a company homepage is invalid
- `work_location_type` (string|null): Work arrangement: on_site, remote, hybrid

Output parameters:

- `hasMore` (boolean)
- `statusOrder` (array)
- `subStatusOrder` (object)
- `totalCount` (integer)
- `trackedJob` (object)
- `trackedJobs` (array)
- `trackerWebUrl` (string)

### `tracker_add` (~382 tokens)

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_company
\- `notes`: 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.

Input parameters:

- `job_id` (string, required): The job ID from jobs.search results
- `notes` (string): Notes about this job
- `status` (string): Initial tracking status: saved, applied, interviewing, offered, archived
- `sub_status` (string): 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; interviewin…

Output parameters:

- `hasMore` (boolean)
- `statusOrder` (array)
- `subStatusOrder` (object)
- `totalCount` (integer)
- `trackedJob` (object)
- `trackedJobs` (array)
- `trackerWebUrl` (string)

### `tracker_update` (~350 tokens)

Updates details of a tracked job (notes, deadline, salary, tags).

\**Input:**
\- `tracked_job_id`: The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required)
\- `notes`: Updated notes
\- `deadline`: Deadline date (ISO 8601 format)
\- `salary_offered`: Salary amount
\- `salary_offered_type`: Salary type: year, month, week, day, hour
\- `tags`: 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.

Input parameters:

- `deadline` (string): Deadline date in ISO 8601 format
- `notes` (string): Notes about this job
- `reminder_at` (string): ISO 8601 datetime, e.g. "2025-03-15T10:00:00Z" (must be in the future, or empty to clear)
- `salary_offered` (number): Salary amount
- `salary_offered_type` (string): Salary type: year, month, week, day, hour
- `tags` (string): Comma-separated tags (e.g., "remote,startup,tech")
- `tracked_job_id` (string, required): The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required)

Output parameters:

- `hasMore` (boolean)
- `statusOrder` (array)
- `subStatusOrder` (object)
- `totalCount` (integer)
- `trackedJob` (object)
- `trackedJobs` (array)
- `trackerWebUrl` (string)

### `tracker_update_status` (~347 tokens)

Updates the status of a tracked job.

\**Input:**
\- `tracked_job_id`: The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.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.

Input parameters:

- `status` (string, required): New status: saved, applied, interviewing, offered, archived
- `sub_status` (string): 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; interviewin…
- `tracked_job_id` (string, required): The tracked job ID — `trackedJobs[].id` from tracker_list output, distinct from `trackable.id` and `job.id` (required)

Output parameters:

- `hasMore` (boolean)
- `statusOrder` (array)
- `subStatusOrder` (object)
- `totalCount` (integer)
- `trackedJob` (object)
- `trackedJobs` (array)
- `trackerWebUrl` (string)

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/foundrole-jobs-mcp-proxy/www#diagnostics

## Score history

- 2026-08-03: 79
- 2026-08-02: 78
- 2026-08-01: 78
- 2026-07-31: 78
- 2026-07-30: 73
- 2026-07-29: 73
- 2026-07-28: 73
- 2026-07-27: 73
- 2026-07-26: 73

## Links

- Remote endpoint: https://www.foundrole.com/mcp
- Repository: https://github.com/foundrole/jobs-mcp-proxy
- Website: https://www.foundrole.com/ai-search-mcp
- Changelog RSS feed: https://verifymcp.io/servers/foundrole-jobs-mcp-proxy/www/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/foundrole-jobs-mcp-proxy/www/changelog.json
- HTML version of this page: https://verifymcp.io/servers/foundrole-jobs-mcp-proxy/www
