Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
JOBWATCH_CONFIGYesPath to the jobwatch watchlist YAML file. The MCP server reads the watchlist from this environment variable.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}

Tools

Functions exposed to the LLM to take actions

NameDescription
find_boardA

Find a company's job board by name or by a job/careers link. Returns entries for the watchlist. A guessed board name can belong to another company: check the sample titles before adding one. Google (with YouTube and DeepMind) is one board, google:google (its US roles; google:google/any for all). So is Amazon (with AWS), amazon:amazon (its US roles; amazon:amazon/any for all). A Workday, Oracle Recruiting Cloud or Jibe board that isn't found by name is found from a link to a job on it. An Avature careers portal is host/portal (avature:careers.initech.example/careers); a name finds one only at name.avature.net/careers, so give a job link from any other. An iCIMS careers site is icims: (careers-.icims.com), or the whole host for another (icims:jobs-acme.icims.com); a name finds one at careers-.icims.com. A Jobvite careers site is jobvite: (jobs.jobvite.com/); a name finds one there. Hacker News' "Who is hiring?" thread is one board, hn:whoishiring (hn:whoishiring/N: the last N months'), found by "Hacker News" or the news.ycombinator.com/submitted?id=whoishiring link. Use it before add_board; to track one job from its link, use add_application instead.

list_boardsA

The boards on the watchlist (entry, display name, careers: the board's own page, careers_link: the company's own careers site when the watchlist gives one) and where the watchlist file is. Use it to see what fetch_jobs checks; add_board and remove_board change it.

add_boardA

Add a company's board to the watchlist, so fetch_jobs checks it from now on. Find the entry with find_board first and check its sample titles: a guessed board name can belong to another company (list_suggested_boards gives entries for companies whose jobs keep coming in from alerts or HN). Adding one that's already there only updates its name and careers link. For Google, leave name empty: each role keeps its own employer (Google, YouTube, DeepMind). Creates the watchlist when there is none yet. The watchlist is rewritten (a copy of the old one is kept as .bak; comments in a hand-written file are not kept).

remove_boardA

Take a board off the watchlist, so fetch_jobs stops checking it. Jobs and applications already recorded from it are kept. The watchlist is rewritten, with a copy of the old one kept as .bak.

list_suggested_boardsA

Companies to watch: those whose jobs came in from job-alert emails (import_job_alerts), add_application or posts in HN's Who is hiring thread (fetch_jobs, when it's watched) while their board isn't on the watchlist, ranked by how many of their jobs pass the watchlist's filters, recent ones counting more. Each: company, matching_jobs, last_seen, board (source:board, or null), board_found (posting: one of its jobs is on that board, or its HN post links to it; name: found under its name, so check with find_board's sample titles that it's theirs), careers, sample_titles, and add_board: the arguments to pass to add_board to watch it (null when no board was found: find_board with a link to its careers page may find one). dismiss_suggested_board stops suggesting one. rescan picks up HN posts kept before (see its description). Suggest; let the person decide which to add.

dismiss_suggested_boardA

Stop suggesting a company in list_suggested_boards, when the person doesn't want to watch it. Its jobs stay tracked. To watch one instead, use add_board with its add_board arguments.

fetch_jobsA

Check every board in the watchlist and record new roles. Returns counts, each board that failed to load (skipped; the rest are still recorded), and warnings: a board whose hosted job pages are offline while its jobs are still listed, which needs the company's careers site (add_board with careers). Run it before get_digest, which lists the new roles themselves.

get_digestA

New jobs that pass the watchlist's filters, best first (fit score when scored, then keyword relevance), with people the user knows at each company. Call fetch_jobs first to pick up today's postings. This is for finding jobs to consider; for jobs already queued use list_queued_jobs, and for applications use list_applications. total is how many matched before the limit (jobs left out stay new for the next digest). not_scored, when set, says why a job is never fit-scored (a Hacker News post listing several roles). pace, unless the user turned it off: applications sent today against how many they aim for a day (daily) and the most (max); once met, suggest the rest wait for tomorrow, but never refuse to help.

get_jobA

Everything about one job, by key or posting id: the full posting text, pay, tracking (status, note, next step, follow-up), its fit score against the resume (score, must-haves met, gaps, and requirements: each requirement with its verdict, met/partial/not_met, and the resume's words backing it; scores saved before jobwatch kept these have none), people the user knows there plus a LinkedIn search for a referral, skills it asks for that the resume doesn't show, what was sent with the application, and candidate_home: the company's page where the person signs in to see the application's status (Workday only; each company has its own account). link_note, when set, says the board's hosted job pages are offline and where to apply instead (url is then the company's careers site, when the watchlist gives one). With no fit score, unscored_reason says why ({code, text}: no_text means it needs its posting, a link via mark_job(url=) or the text pasted; queued means it's in the page's background scorer's line; many_roles, a post listing several roles, is never scored). duplicate_of is the job already applied to, queued or skipped that this one is (maybe) the same opening as: key, title, status, date, why, strong (a shared req or posting id; false: the same title only, so check it's a different opening), reposted, and text, the warning to heed; null when there's none. Check it before drafting a referral request or an application. Use it to tailor a resume or decide whether to apply; for only what was sent use get_application_package, and for a call or interview use get_interview_prep.

mark_jobA

Record a job's status: new, shown, queued (to apply to next), applied, screening, interviewing, offer, rejected, withdrawn or skipped (omit status to keep it and only update the rest). key is the job's key, its posting id, or its company's name when that names one job (the one queued or applied to there); when it names several, nothing changes and the error lists them. Use applied only after the person has submitted the application themselves. add_note adds a dated line to the note, keeping what's there: prefer it for news ("recruiter replied: onsite only"); note replaces the whole note. next_step says what happens next ("recruiter screen Tuesday"); follow_up is the day to act (YYYY-MM-DD or +N days); applied_on is the day applied, if not today. url sets the link of a job added by hand (its posting, or the company's careers site once the posting is gone); when the job has no posting text and the link is to one job on a supported board, the posting is read from it (text, pay, places), so it can be scored. text sets its posting's text, pasted (found later, or from a copy once the posting is gone), so it can be scored and prepped. An empty string clears a field. For a job jobwatch doesn't track yet, use add_application. Queuing a job that's (maybe) the same opening as one applied to or queued still queues it, and the reply ends with the warning: tell the person.

add_applicationA

Add a job jobwatch didn't find (a referral, a recruiter, LinkedIn...), so everything is in one place: an application (only after the person has applied themselves), or status queued for one they're considering. A url to one job on Greenhouse, Lever, Ashby, Workable, Workday, Rippling, Google Careers (a .../jobs/results/ link), amazon.jobs (a .../jobs/ link), Oracle Recruiting Cloud (an ...oraclecloud.com/.../sites//job/ link), SmartRecruiters (a jobs.smartrecruiters.com// link), an Avature portal (a .../JobDetail// link) or iCIMS (a .../jobs///job link) or Jobvite (a jobs.jobvite.com//job/ link) is read in full (company and title may be left out). A LinkedIn job link is never read (LinkedIn's robots.txt disallows it): give company and title with it (and text to score it), and it's tracked on the company's own board when the same job is found there. Otherwise give company and title, and text (the posting, pasted) so it can be scored. For a job jobwatch already tracks (it came from get_digest or get_job), use mark_job instead; for the jobs in job-alert emails, import_job_alerts. When it's (maybe) the same opening as one already applied to, queued or skipped, the reply ends with that warning: tell the person.

import_job_alertsA

Track the jobs in job-alert emails (LinkedIn, Built In, Indeed; other senders with a generic reader). Search the person's mail for them first, e.g. from:jobalerts-noreply@linkedin.com, from:builtin.com, from:jobalert.indeed.com, and pass each message in; jobwatch never needs a mail password. Links lose their tracking parameters. Each job whose title, place and pay pass the watchlist's filters is looked for on the company's own board (a link to a supported board is read from there); job sites' pages are read only when their robots.txt allows (LinkedIn's and Indeed's don't, so the email's details are used). Jobs already tracked are left alone (known); new ones show up in get_digest, with via saying where they came from. Returns counts and each job: key, result (new, known, duplicate: twice in these emails), how (board, posting, page or email), filtered (why the filters leave it out of the digest, or null) and duplicate_of (the job applied to, queued or skipped that it's maybe the same opening as, as get_job gives it, or null). For emails about the person's applications (confirmations, rejections, interviews), use read_status_emails.

read_status_emailsA

Read emails about the person's applications (a "thank you for applying" confirmation, a rejection, an interview invitation or scheduling link, a take-home assignment, an offer, a recruiter's reply) and PROPOSE what changes; nothing is recorded. Search the person's mail first (e.g. their applications' companies, or "thank you for applying", "your application", "interview"), and pass each message in; jobwatch never needs a mail password. Present the proposals to the person and only call mark_job for the ones they confirm, with the proposal's mark_job arguments (status, add_note, next_step, follow_up). Returns proposals (key, company, title, current_status, suggested_status (null: only a note), kind, note, next_step, email (date, sender, subject), confidence, why, mark_job), unmatched (emails about no tracked application, with the company guessed: offer to add it with add_application, or say it's an application it can't tell apart), nothing_new (emails that add nothing: already recorded or already past that stage) and other (the count of emails that aren't about an application). A status only moves forward: a late confirmation for an application already interviewing is not a proposal. For job-alert emails use import_job_alerts.

list_applicationsA

Every application (applied or a later stage) and where it stands, follow-ups due soonest first; candidate_home is the company's page for checking its status, when it has one (Workday). Use it to see what needs a follow-up; for jobs not applied to yet use list_queued_jobs, and for any status use list_jobs. quiet is set on an application with no stage change or note for weeks (the watchlist's quiet: days per stage): days, since, posting_open, long (quiet so long that it sorts below the fresher ones), move (nudge: a short check-in to the recruiter or a contact, or close: likely closed, ask the person whether to mark it rejected or withdrawn; never change it on your own), advice, and contacts the person knows there.

get_compsA

Open applications side by side, to compare offers and processes: for each, its stage, applied day, next step and follow-up, pay as posted, places, fit score (must-haves met, top gaps), people the person knows there, and the compensation details they were told (base, bonus, equity, sign-on, asked, offered, note; set them with set_comp), and the company's health (set it with set_company_health; stale when older than 90 days: research it again). best says which opportunity is highest in posted pay, base, offered and fit. suggestion ranks them by rules (career value from the company's kind and the job's role, pay against the person's target, fit, how far along, company health) with the weights, each part's score and input, and a reason: explain it, and say what is missing (no health kept, no kind or role, no pay known) rather than guessing. Use it when the person asks how their opportunities compare; for one application's status use list_applications.

set_compA

Keep what a recruiter told the person about pay for a job, so get_comps can put it next to the others, and what the job is for their career (role, career_note). Only the fields given change; an empty string clears one. Write amounts the way they were said ("165-195K", "$215,000"): the first amount found is read to mark the highest. Returns what is kept for the job.

set_company_healthA

Keep what is known of a company's health, per company, for get_comps to show and weigh. Search the web yourself (jobwatch fetches none of these sites) and record what you found with its source links and the day; say so when you could not find something, and leave that field out rather than guessing. Only the fields given change; an empty string clears one. Returns what is kept, with how old it is.

list_queued_jobsA

Jobs queued to apply to, oldest first, with fit scores, notes, people the user knows there (ask them for a referral before applying) and warnings to check first (pay, place, flagged text). The first warning, and duplicate_of, say when it's (maybe) the same opening as one already applied to, queued or skipped: read them before asking anyone for a referral. Use it to pick the next application; jobs get here through mark_job with status queued. For applications already sent use list_applications.

check_postingsA

Check that the postings of queued jobs and open applications still take applications, and record the ones that closed or came back. result is open, closed, reopened, or unknown (check it yourself); an open job's detail may say its board's hosted pages are offline and where to apply instead. Run it before working through list_queued_jobs, so time isn't spent on closed postings.

list_jobsA

Tracked jobs with their tracking fields, newest first, including closed postings. A plain list by status (e.g. every skipped job); for ranked new jobs use get_digest, for the next to apply to list_queued_jobs, and for follow-ups list_applications.

find_duplicatesA

Jobs tracked twice: pairs of tracked jobs, open or closed, where the person queued, applied to or skipped one and the other is the same opening (strong: a shared req or posting id, from a title, note, posting text or link; why says which, "reposted as req ..." for a repost) or maybe the same (why "same title": check it's a different opening). The same opening first, applications first. Each: why, strong, and both jobs (key, company, title, status, date, closed), the one acted on first. Read-only: the person decides what to skip (mark_job). For one job, get_job's duplicate_of says the same.

read_profileA

Who an interviewer or contact is: their roles, from the text of their LinkedIn experience page, for interview prep. Each: title, company, start, end ("Present" if current), duration, location, workplace (Hybrid, Remote or On-site) and bullets (the description). The page's sidebars and footer are dropped. This only parses text it is given: jobwatch never reads linkedin.com (its robots.txt disallows it), so get the page text through the person's own browser. Returns an error when no roles are found.

get_companyA

Everything tracked at one company, whatever the status of its jobs (new, queued, applied, screening, interviewing, offer, rejected, withdrawn, skipped) and open or closed. company, counts (jobs by status), and jobs: each with key, title, status, posted, applied_at, closed, next_step, follow_up, due, note, package (what was saved: files, answers, note) and duplicate_of (see get_job); contacts: people the user knows there, with find_referral, a LinkedIn search for someone who could introduce them; watch: whether the company's board is on the watchlist and, when it isn't, add_board (the entry and name to pass add_board) and command. Closed postings never acted on are only counted (closed_unacted), so are open ones not acted on that the filters leave out (left_out, with left_out_by: filter -> count) unless every_role, and the other open ones not acted on are listed up to 25 (more_open). also names other companies the name matched. Returns an error when none matches. Use it when the person names a company and you don't know which stage it's at; for one job's full text, fit and prep use get_job, for every application list_applications, and for all jobs of one status list_jobs.

rate_contactA

Record what the person says about someone they know at a company: use (a good person to ask for a referral: listed first wherever contacts are), skip (never suggest them, e.g. never answers messages) or clear (forget it), with an optional short note that is shown with their name. Call it when the person tells you whom to ask or not to ask; it only changes how contacts are ordered and listed. Returns the connection (name, company, position, verdict, note). Errors when no connection (or more than one) has that name: then use their profile link.

save_application_packageA

Keep what was sent with an application, as copies: files (local paths to the resume PDF, cover letter... exactly as uploaded), answers (the form's questions and the answers given, [{question, answer}]; replaces any saved before) and note (a cover letter or message pasted into the form). Call it once the person has submitted, with what they actually sent; get_application_package reads it back.

get_application_packageA

What was sent with an application: files kept (with their folder), form answers, note, and the day the posting was saved as it read then (posting.md in the folder). Use it to check exactly what was sent; for a full prep sheet use get_interview_prep, and for the posting and fit use get_job.

find_past_answersA

Form answers the person gave on earlier applications (kept by save_application_package), newest application first: key, company, title, applied, question and answer; without a query each question once, with asked (how many applications had it). Use it before filling a form, to reuse what was answered to "reason for leaving", "notice period" or "salary" instead of writing it again; for everything sent with one application use get_application_package.

get_interview_prepA

A prep sheet for a recruiter call or interview: stage and next step, each requirement and responsibility in the posting next to the closest resume line (quoted, never written), gaps to be honest about, what was sent, questions to expect and to ask, and the posting. For an application added by hand, the posting is found on a watched board by its requisition id. markdown is the sheet ready to read. Also: brief, the company as the posting and the person's own notes tell it (about: the posting's lines; facts; notes; contacts: people they know there; source), nothing looked up elsewhere, so say it's from the posting; pay, the posted range (posted, posted_min, posted_max), the person's target (target, and target_max when it's a range) and how it sits against the range (target_note); and role_questions, questions for this role written from the posting's asks (questions_note says where they came from; empty: expect's generic questions stand). The person's private pay floor is never returned here (pay.floor_withheld says one is set): don't ask for it or guess it. With draft_answers, drafted holds the drafted questions and draft_note how they were made, or why there are none. practised holds the answers the person kept from mock interviews (jobwatch ask --job KEY --mock): question, answer as they said it, and improved, the tightened version built from their own words and stories. Present a drafted answer as the person's only where it cites their stories. story_gaps lists what a story would help with (ask, why): asks with nothing close on the resume, drafted questions with no story yet, missing must-haves; to fill one, interview the person and keep what they confirm with save_story. Use it before a call; get_job and get_application_package give the raw pieces.

save_storyA

Add a story to the person's story file (the watchlist's stories:, or stories.yaml beside it, which the watchlist then names), for drafted interview answers and mock interviews. Use it after interviewing the person about one of get_interview_prep's story_gaps: ask one question at a time; if you offer typical details to jog their memory, say they're common patterns, not their case; keep their real role (took part is not led); keep internal system names, people's names and countries out. Only what they confirmed goes in did, hard and result; the rest goes in avoid. Show them the story and save it only after they say yes. Returns the story as saved, the file and how many stories it has.

list_skill_gapsA

Skills today's matching jobs and the person's applications ask for, most in demand first, each with on_resume, how many jobs mention it, how many scored jobs list it as a missing must-have, and ways to learn it: curated courses and certifications (official pages, each with a rough time and whether it fits the timeline) and searches on Coursera, LinkedIn Learning, edX and nearby colleges. Also fit-score gaps no course closes (clearance, citizenship, degree, travel). Recommend only from these links; never suggest claiming a skill the resume doesn't show. For one job's gaps use get_job; to prepare for a call use get_interview_prep.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A3.9/5.0

Scored across 30 tools

Disambiguation4/5

Most tools have clearly distinct purposes, and the descriptions explicitly cross-reference adjacent tools such as mark_job vs add_application and get_digest vs list_queued_jobs. There is still some boundary overlap among retrieval/listing tools (get_job, get_company, list_jobs, list_applications, list_queued_jobs, get_digest), though the descriptions generally resolve it.

Naming Consistency5/5

Names are consistently snake_case and overwhelmingly follow a verb_noun pattern: list_boards, add_board, remove_board, get_job, mark_job, save_story, etc. Minor abbreviations like set_comp and get_comps are used consistently and do not disrupt predictability.

Tool Count2/5

With 30 tools, the surface exceeds the threshold where a tool set becomes heavy for an agent to select from reliably, even for a broad job-search assistant domain. Several clusters (jobs, applications, emails, prep, boards, skills) could be consolidated or grouped to reduce cognitive load.

Completeness4/5

The surface covers a remarkably broad lifecycle: board discovery, job fetching/importing, application tracking, email status proposals, interview prep, compensation comparison, contacts, stories, and skill gaps. Minor gaps remain around explicit configuration of watchlist filters/resume, and management operations such as listing or deleting saved stories, but most workflows are covered.

Maintenance

ActivityMaintained
ResponsivenessNo issues