Skip to main content
Glama

FreeApply

Free AI job applications that run on your computer. FreeApply finds jobs that fit your settings, applies through the AI app you already use, tracks every application in a local dashboard and checks Gmail for employer replies. Any role, any field.

Website: https://www.mybotsai.com · Install: https://www.mybotsai.com/install/ · Downloads: https://www.mybotsai.com/appserver/ · Release notes: release-notes/ · Source: https://github.com/FreeApply/freeapply

Current version: 1.0.2 (notes). The app and its legal documents share one version number.

What it does

  • Finds jobs that fit: roles, pay floor and locations from your settings, on the job sites you choose. Duplicates and reposts it has already tracked are skipped.

  • Applies for you on employer sites and job boards with your real details, your résumé and answers you saved once, at a measured pace.

  • Never invents experience. Cover letters and answers are checked against your résumé and settings before they are used.

  • Knows when to stop. CAPTCHAs, new accounts, passwords and questions your settings don't answer go to the Issues tab for you.

  • Tracks everything in a dashboard at http://127.0.0.1:7878, reachable only from your computer.

  • Watches for replies with your AI app's Gmail connector, every 4 hours by default.

Related MCP server: cv-job-assistant

Install

App

How

Claude Desktop

Download freeapply.mcpb and double-click it, or drag it into Settings → Extensions. Nothing else to install.

Claude Code, Cursor, VS Code, Windsurf

Windows: irm https://www.mybotsai.com/appserver/install.ps1 | iexmacOS and Linux: curl -fsSL https://www.mybotsai.com/appserver/install.sh | bashNeeds Node.js 22.13 or newer. The installer checks the package's signature, then asks before adding FreeApply to each app it finds.

Claude Code, from this repository

/plugin marketplace add FreeApply/freeapply, then /plugin install freeapply@freeapply

Any other MCP app

Unpack freeapply.mcpb (it is a ZIP file) and add a stdio server that runs node /path/to/freeapply/src/main.js.

To update, install the new version the same way. To uninstall, see https://www.mybotsai.com/install/#uninstall. Your data in ~/.freeapply stays until you delete that folder.

First run

  1. Restart your AI app and say "Set up FreeApply". The dashboard opens.

  2. Read and accept the Terms of Service and Privacy Policy there yourself (18+). Until you do, every agent tool except freeapply_status and freeapply_open_dashboard refuses to run, and the agent can never accept for you.

  3. Fill in Settings: résumé (PDF, DOCX, TXT or MD), name and email, desired roles, minimum pay, locations, work authorization and the job sites you use. The agent applies nowhere until these are filled.

  4. Sign in to your job sites in the browser your AI app uses, then say "Find me jobs and apply".

With a Gmail connector, setup also schedules the reply check, which stars replies, labels them, or both (your choice in Settings).

Guarantees

  • Facts about you come only from your résumé, your settings and what you tell the agent. It never invents experience.

  • It never types passwords, creates accounts or solves CAPTCHAs. Those jobs are flagged for you.

  • Signed workflow. The procedures, server instructions and hard limits ship in agent/workflow.signed.json, signed with our release key. Any edit fails verification and locks the tools until the official copy is restored. Pacing, duplicate checks, the pay floor and the truthfulness check are enforced in the tool code, not just asked of the AI.

  • Your data stays on your computer, except what your data-sharing choices send. The dashboard accepts only local requests that carry its own header.

Data sharing

Choice

United States

Everywhere else, or with Global Privacy Control

Anonymous usage statistics

On by default, one-click opt-out

Opt-in

Job-market data (no name or contact details; sold only as totals covering 5+ installations)

On by default, one-click opt-out

Opt-in

Recruiter Talent Pool (contact details and résumé, sold to recruiters)

Opt-in

Opt-in

Product update emails

Opt-in

Opt-in

The region comes from your profile country, otherwise your computer's language and time zone; unknown counts as outside the US. In Settings → Data sharing you can preview exactly what is sent, sync now, and delete everything already shared. Details: Privacy Policy.

The dashboard shows one card labeled "Sponsored", chosen on your computer from a signed pack. No ad scripts, no trackers, and no data is sent to show it.

Dashboard

Overview, Applications, Replies, Issues and Settings, with the Terms, Privacy Policy, Disclosures and Recruiter Terms linked in the footer. The Needs you tab collects what needs you, in plain words:

  • Questions: what a form asked that your settings don't answer, each as a simple question you answer by typing, from a dropdown or by picking options. A question several jobs ask is shown once, and one answer goes to all of them; questions you already answered aren't asked again. The jobs then go back in the queue.

  • Accounts to create: one card per sign-up page, however many jobs wait on that account, with its link and a FreeApply Autofill bookmarklet that fills your name, email, phone and location on sign-up pages. Passwords stay with your browser or password manager.

  • Blocked: what the site asked for (a "prove you're a person" check, a code, a warning), with "I applied myself", "Try again later" and "Skip this job".

Configuration

What

Where

Data folder

~/.freeapply, or the FREEAPPLY_DATA environment variable

Use an existing database in place

~/.freeapply/config.json: {"db": "C:/path/jobs.db"}, or FREEAPPLY_DB

Dashboard port

FREEAPPLY_PORT (default 7878; the next free port is used if it is taken)

Dashboard only

node agent/src/main.js --dashboard

Flags

--data <dir>, --db <file>, --port <n>, --skills-dir <dir> (repeatable; skill files are kept equal to the signed workflow)

Tools

18 tools, each with a title, annotations (read-only, destructive, idempotent) and a description of every parameter: freeapply_status (can FreeApply run, plus the signed procedure for a task), freeapply_open_dashboard, freeapply_get_settings (all settings or just the sections a step needs), freeapply_update_settings (settings, the résumé text and profile, and the AI models scan that picks a model for each part of the work), freeapply_fetch_posting (fetches and trims postings on your computer to save tokens, with their ATS keywords), freeapply_claim_job (claim or skip a job, with the duplicate, job-site and pay-floor checks), freeapply_check_text (truthfulness check; saves a passing cover letter as a PDF), freeapply_user_answers (get a job's answers or save a reusable one), freeapply_find_site_account, freeapply_clear_to_submit (clearance before each submit, and the unattended run's budgets), freeapply_update_job (your side: found to applied), freeapply_report_site_problem, freeapply_autorun (start or finish unattended runs), freeapply_list_jobs, freeapply_job_stats, freeapply_reply_check (start or finish a Gmail check), freeapply_record_outcome (what an employer did, from an email or the user), freeapply_shared_data (preview or send shared data). Removing a job is a dashboard action only (Applications → Remove); the agent has no tool for it. Every call is checked against the tool's parameters first: a missing, unknown or wrongly typed parameter returns one error naming each problem, and nothing changes.

Skills for Claude Code: freeapply-setup, freeapply-apply, freeapply-replies. Each points to its signed procedure.

Check a download

Every package comes with a .sig.json file holding its SHA-256, signed with an Ed25519 key whose private half never leaves our offline machine. The public keys are in agent/keys/. Compare the checksum with the one in latest.json:

Get-FileHash .\freeapply.mcpb -Algorithm SHA256      # Windows
shasum -a 256 freeapply.mcpb                         # macOS, Linux

The installer and the app's own update check do this and the signature check for you; a download that doesn't match is refused.

This repository

Path

What

agent/

The app: an MCP server in Node.js with no dependencies, the dashboard (web/), the legal texts (web/legal/), the signed workflow and the public keys. It is also the Claude Desktop extension (manifest.json).

skills/

Claude Code skills that point to the signed procedures

.claude-plugin/, .mcp.json

Claude Code plugin and marketplace files

release-notes/

What changed in each version

LICENSE

MIT License for the source code

License

The source code is released under the MIT License. The FreeApply name and logo are not covered by it; use of FreeApply and of the services we host is governed by the Terms of Service.

Contact

MyBotsAI · mybotsai@gmail.com.

Available Tools

18 tools
freeapply_autorunStart or finish an unattended runA

Starts and finishes unattended (scheduled) runs, and records the schedule. Unlike freeapply_status, which only shows the run state, it changes it; the schedule itself is a scheduled task in the user's AI app. Use start at the beginning of every scheduled run and finish at its end, also when stopping early. Use schedule_created or schedule_removed after you create or delete the scheduled task, so the dashboard shows it. Not in a session the user runs by hand. Behavior: start opens a run only when one may go now; another start while a run is going, or within 10 minutes of its planned end, gets go false. During the run, freeapply_clear_to_submit with the run_id ends it when a budget runs out or the user presses Stop. finish releases the run; finishing a run that already ended is harmless. Parameters: action picks the step. finish needs the run_id from start and takes summary, one line on the run, e.g. "applied 4, needs you 2" (up to 500 characters). Returns: start {go: true, run_id, minutes, max_applications, sites}, or {go: false, reason} (auto-run off, Terms or setup missing, daily cap reached, or another run going); then stop at once, quietly. finish {finished, applied_this_run}, null for a run no longer active. schedule_created and schedule_removed {schedule_created}. Errors: finish without run_id, or another action.

NameRequiredDescriptionDefault
actionYesstart or finish a run, or report the scheduled task.
run_idNoFor finish: the run_id that start returned.
summaryNoFor finish: one line on the run.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With annotations already declaring readOnlyHint=false and destructiveHint=false, the description goes well past them: it explains the gating rule (start returns go:false if a run is going or within 10 minutes of its planned end), how freeapply_clear_to_submit with run_id terminates a run, that finish releases the run and is harmless when repeated, the exact return shapes for each action, and the two error cases. This is the full behavioral burden discharged.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and the sibling distinction are front-loaded, then labeled sections (Behavior, Parameters, Returns, Errors) keep the dense content navigable. It is long and information-dense — near the upper limit for a single tool description — but almost every clause is load-bearing given there is no output schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

A four-action tool with no output schema and cross-tool coupling to freeapply_clear_to_submit; the description covers returns for each action, the go:false reason categories, error conditions, and the call-site contract. Nothing needed 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.

Parameters4/5

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 real meaning beyond the schema: run_id must be the value start returned, summary is "one line on the run" capped at 500 characters, and action is framed as the step selector whose effects vary per enum value. The 500-character limit and the required pairing of run_id with finish are details the schema does not carry.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb pair and resource ("Starts and finishes unattended (scheduled) runs, and records the schedule") and explicitly distinguishes itself from freeapply_status by noting that status only shows run state while this changes it. An agent can tell which tool to pick without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use for each action (start at the beginning of every scheduled run, finish at its end including early stops, schedule_created/schedule_removed after creating or deleting the scheduled task) and an explicit exclusion ("Not in a session the user runs by hand"), plus the named alternative freeapply_status. 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.

freeapply_check_textCheck text and save the cover letterA
Idempotent

Checks a cover letter or free-text answer against what the user really has, and turns a passing cover letter into a PDF to upload. Unlike freeapply_update_job, which only records the result, it is where every piece of prose is checked before you type or attach it. Use it before typing any written answer or attaching any letter, and again after each fix. Not for short fields taken straight from the settings, such as a name, a date or yes/no. Behavior: flags every skill, tool, number or claim that the résumé, settings, highlights and saved answers don't support. Without save it changes nothing. With save a passing letter becomes a PDF in the documents folder, kept with the job; a failing one is never saved, saving again replaces the file, and a job already applied to is refused. Parameters: kind cover_letter also checks the user's chosen length, their sign-off, leftover placeholders and that the company is named; answer, the default, checks facts only. job_id adds the posting's keywords, counts numbers from the posting and the user's answers for that job as facts, and is needed for save. company names the employer when there is no job_id. For a letter, pass save from the first call so a passing letter is checked and saved at once. Returns: {ok, problems}, problems being plain sentences to fix, remove or ask the user about. With job_id also keywords {used, unused}: the posting's supported skills this text uses, and those it could still use. With save also file {path, name, bytes}, or a note why it wasn't saved. Errors: save without kind cover_letter and a job_id, or an unknown job_id. If the résumé was never saved, most claims are reported as unsupported.

NameRequiredDescriptionDefault
kindNoWhat the text is. Optional; default answer.
saveNoSave a passing cover letter as a PDF. Optional; default false.
textYesThe cover letter or answer to check, exactly as you will type or attach it.
job_idNoThe job it is for. Optional; needed for save.
companyNoThe employer, when there is no job_id. Optional.

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds substantial behavior beyond the annotations: without save nothing changes, with save a passing letter becomes a PDF, a failing one is never saved, saving again replaces the file, and a job already applied to is refused. It also explains unsupported claims, error cases, and the résumé-unsaved edge case. This does not contradict the annotations; it enriches them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but front-loaded and structured as purpose, usage, behavior, parameters, returns, and errors. Every sentence contributes operational detail, including edge cases and return shapes, because no output schema exists. There is little redundancy despite the density.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description supplies the return shape {ok, problems} and conditional keywords/file data. It covers save behavior, error conditions, prerequisite risks around an unsaved résumé, and parameter-specific checks. Nothing essential for correct invocation appears to be missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is 100%, the description adds real meaning beyond the schema: kind cover_letter also checks length, sign-off, placeholders, and employer naming, while answer checks facts only. It explains that job_id adds posting keywords and is needed for save, and that company names the employer when job_id is absent. It also advises passing save from the first call for letters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb and resource: checking a cover letter or free-text answer and turning a passing cover letter into a PDF. It explicitly distinguishes itself from freeapply_update_job by saying that sibling only records the result, while this tool is where prose is checked. An agent can identify the tool without opening the schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit timing: use before typing any written answer or attaching any letter, and again after each fix. It also states an exclusion: not for short fields taken straight from settings, such as name, date, or yes/no. The alternative freeapply_update_job is named and contrasted.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeapply_claim_jobClaim or skip a jobA

Claims a job before you work on it: runs the duplicate check, applies the user's rules and starts tracking it, returning the job_id every later call needs. Unlike freeapply_list_jobs it adds a job, and unlike freeapply_update_job it makes the job's first record. Use it before opening any application form, and to record a job you reviewed and won't pursue (status skipped, with status_note) so it isn't reviewed again. Not for changing a job you already claimed. Behavior: adds the job unless, in this order: a posting id already tracked returns that job (existing: true; nothing added); a job site the user didn't choose, or one signed out or paused, is refused (refused says why, sites lists the ready ones); the same company and title as a job already applied to is refused as a repost; posted pay below the user's minimum is saved as skipped (rule: pay_floor). Parameters: title and company are required; company is the employer, not a staffing firm, when you can tell. Pass external_id whenever the site shows the posting's id: it catches reposts. url or source tells which job site it came from; the URL just read by freeapply_fetch_posting keeps its keywords. pay_min and pay_max feed the pay floor; fit_score is 0 to 100, as the apply procedure scores it. Returns: {job_id, existing, status, rule, earlier}. earlier lists up to 20 other jobs at the same company as {id, title, company, status, same_title}; if an applied one is clearly the same role under another title, mark this one skipped with freeapply_update_job. Errors: a missing title or company.

NameRequiredDescriptionDefault
urlNoThe posting's URL; also tells which job site it came from.
titleYesJob title, as posted.
sourceNoWhere it was found: a job site id (linkedin, indeed, company_sites, ...) or referral.
statusNofound to work on it (default), or skipped to record a job you won't pursue.
companyYesEmployer name, as posted (not the staffing firm's name, if known).
pay_maxNoHighest posted pay as a number.
pay_minNoLowest posted pay as a number: annual, or hourly if posted hourly.
locationNoLocation as posted.
pay_textNoPay exactly as posted, e.g. "$90k-$110k".
apply_urlNoWhere the application form is, if different.
fit_notesNoWhy it fits or doesn't, in one sentence.
fit_scoreNoFit from 0 to 100, scored as the apply procedure describes.
work_modeNoremote, hybrid or onsite, as posted.
descriptionNoShort description or key requirements.
external_idNoThe posting's id on its source site; finds the same posting again, reposts included.
status_noteNoWhy it was skipped, in one plain sentence; for status skipped.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond annotations by explaining duplicate handling, site eligibility checks, repost detection, pay-floor skipping, return fields, and errors. Annotations already cover the safety profile, but the description still adds substantial behavioral context about ordering and side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action, then organizes behavior, parameters, returns, and errors into clear labeled sections. It is dense and somewhat long, but most sentences carry operational value for a complex mutation tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, but the description documents the return shape and the earlier list. Given the 16-parameter schema, annotations, and behavioral complexity, it provides enough context for an agent to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description adds meaningful semantics for key parameters such as company vs. staffing firm, external_id for reposts, url/source for site origin, pay_min/pay_max feeding the pay floor, and fit_score range. It does not explain every one of the 16 parameters, but it adds useful meaning beyond the already-rich schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific action and resource: claims a job, runs duplicate checks, applies rules, starts tracking, and returns job_id. It explicitly distinguishes itself from freeapply_list_jobs and freeapply_update_job, so an agent can select it correctly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use guidance: before opening any application form, and for recording skipped jobs. It also states when not to use it—'Not for changing a job you already claimed'—and names the relevant alternative behavior.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeapply_clear_to_submitGet clearance to submitA

Gives the go-ahead for one submit after checking the pace, the user's limits and, in an unattended run, its budgets. Unlike freeapply_update_job, which records the submit afterwards, it comes right before it; recording applied is refused without its clearance. Use it right before every submit, with the job_id. Not early, and not for a job you won't submit now: each clearance counts toward the per-minute pace at once. Behavior: allows at most 3 submissions a minute (or the user's slower setting), keeps the user's daily cap and, for easy_apply, whether the user allows one-click apply. A clearance is for one job, lasts 15 minutes and is used up when freeapply_update_job records applied; asking again for the same job issues a new one. Clearances last only while FreeApply runs. Parameters: job_id gets the clearance; without it you only see the pace. method (default external) matters only for easy_apply, refused while one-click apply is off. run_id, in an unattended run, first checks that run's time and application budgets and the dashboard's Stop button. Returns: {clear, advice, last_minute, limit_per_minute, today, daily_cap}, plus clearance {job_id, expires_at} when clear. clear false: don't submit; prepare the next job and call again later. refused: one-click apply is off; apply on the employer's site or skip the job. stop_run true, with reason: the run must end now; call freeapply_autorun action finish.

NameRequiredDescriptionDefault
job_idNoThe job about to be submitted.
methodNoHow you will submit: external (an employer or ATS form; default), easy_apply (a job board's one-click apply) or email.
run_idNoIn an unattended run only: the run_id that freeapply_autorun start returned.

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Discloses important stateful behavior beyond annotations: per-minute pace, daily cap, one-click apply restriction, 15-minute clearance lifetime, single-use clearance consumed by update_job, and that new requests issue new clearances. It also explains that clearances only last while FreeApply runs and what run_id budget/Stop checks imply.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but appropriately sized for a stateful, policy-driven tool. It is front-loaded with purpose and sibling contrast, then proceeds through usage, behavior, parameters, and return/action handling without wasted sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Although there is no output schema, the description explains the return fields and how to interpret clear false, refused, and stop_run true. Combined with the schema and annotations, it gives an agent enough information to invoke and react to the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Even though schema description coverage is 100%, the description adds meaningful semantics: job_id is what gets the clearance and without it only the pace is shown; method defaults to external and matters only for easy_apply; run_id is for unattended runs and triggers budget and Stop-button checks.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: gives clearance to submit one job right before submission. It explicitly distinguishes itself from freeapply_update_job by explaining that update_job records the submit afterwards and is refused without this clearance.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit timing guidance: use right before every submit with job_id, not early, and not for a job you will not submit now. It also explains what to do when clear is false, when refused due to one-click apply being off, and when stop_run is true with a required follow-up call.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeapply_fetch_postingFetch a job postingA
Read-onlyIdempotent

Fetches one job posting on the user's computer and returns it trimmed, with its form questions, suggested answers and the skills it asks for. Unlike opening the page in the browser it costs few tokens; you still use the browser to fill in and submit the form. Use it to read each posting before scoring or applying. Not for search-results pages or pages behind a sign-in; read those in the browser. Behavior: read-only; one web request from the user's computer. Greenhouse, Lever and Ashby postings are read through their public APIs, other sites as plain page text. Only public http and https pages are fetched: an address on this computer or a local network, or a redirect to one, is refused. The posting is remembered for this session, so freeapply_claim_job can keep its keywords. Parameters: url is the job page or its application form. max_chars caps the description (default 6000, at least 500); description_chars gives its full length. source, a job site id such as linkedin, picks the saved answers meant for that site. Returns: ats, title, company, location, work_mode, pay, description, description_chars, questions (label, required, type, options), suggested_answers (from settings and saved answers; answer anything else only from the résumé or the user) and keywords {matched, missing, coverage}: use matched skills in the posting's words, never claim missing ones; coverage is the matched share in percent, null when the posting names none. Errors: a bad or local address, or a page that can't be fetched, with the reason; then read it in the browser. Next: freeapply_claim_job.

NameRequiredDescriptionDefault
urlYesThe posting's URL: the job page or its application form.
sourceNoThe job site id where it was found. Optional.
max_charsNoLongest description to return, in characters. Optional; default 6000.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond annotations by disclosing per-site API vs page-text behavior, the SSRF-style refusal of local/private addresses and redirects, and session-level caching that freeapply_claim_job depends on. Annotations already cover read-only/idempotent, so this adds real operational context; error handling is summarized but retry semantics for transient failures are not spelled out.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded purpose, then usage, behavior, parameters, returns, errors, and next step — a clean, scannable structure. Slightly dense in the params/returns sentences, but nearly every clause carries information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Even without an output schema, the description enumerates the returned fields including the keywords {matched, missing, coverage} triple and the guidance not to claim missing skills. Errors and the follow-up tool are covered, so an agent can invoke and act on the result without guessing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% so the baseline is 3; the description adds meaning the schema lacks, such as max_chars capping only the description, description_chars reporting full length, and source selecting site-specific saved answers. That is genuine value beyond the schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Fetches one job posting') and immediately scopes it: trimmed, with form questions, suggested answers, and required skills. It explicitly contrasts with the browser alternative and with search-results pages, so an agent can distinguish it from siblings like freeapply_list_jobs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use ('read each posting before scoring or applying') and when-not ('not for search-results pages or pages behind a sign-in; read those in the browser'). It also names the next tool in the workflow (freeapply_claim_job), giving a complete routing decision.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeapply_find_site_accountFind the user's employer-site accountA
Read-onlyIdempotent

Looks up whether the user already made an account on an employer's careers site, and with which email. Unlike freeapply_report_site_problem, which is for job boards such as LinkedIn that signed the user out, it is about an employer's own site. Use it when an application form asks you to sign in or create an account. Not for signing in or up: FreeApply never stores passwords and you never type one. Behavior: read-only. The user records the accounts they make on the dashboard's Needs you tab. Parameters: site is the site's domain or any web address on it, reduced to the domain without www. and matched exactly, so careers.example.com and example.com are different sites. Returns: {domain, email_used, created_at, job_id, note} for a known account, or {domain, account: null}. Known: ask the user to sign in in the browser, then continue in their session. None: record the job with freeapply_update_job status needs_account and the sign-up page as account_url. Errors: a site that isn't a domain or web address.

NameRequiredDescriptionDefault
siteYesThe employer site's domain or any URL on it, e.g. careers.example.com.

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, non-destructive, closed-world behavior, but the description adds substantial context beyond them: no passwords are stored, the user records accounts on the dashboard, and the returned states imply concrete next actions. It also documents the error case for inputs that are not domains or URLs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose, then sibling differentiation, usage guidance, behavior, parameter semantics, return shape, and errors. Despite its length, each section carries operational value for a one-parameter tool that drives a multi-step account workflow.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, but the description supplies the return shape for both known and unknown accounts. It also explains the actions to take in each case and the error condition, leaving no major ambiguity for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

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 site parameter. The description adds important matching semantics: www is stripped, matching is exact, and subdomains such as careers.example.com are treated as distinct from example.com.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: looking up whether the user already has an employer-site account and which email was used. It explicitly distinguishes this from freeapply_report_site_problem, which handles job-board sign-outs rather than employer sites.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear trigger: use when an application form asks the agent to sign in or create an account. It also gives an explicit exclusion: this is not for signing in or up, because FreeApply never stores passwords, and it names the alternative tool for a related but different scenario.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeapply_get_settingsRead the user's settingsA
Read-onlyIdempotent

Reads the user's settings: who they are, what they're looking for and how FreeApply should work. Unlike freeapply_user_answers (answers to single form questions) and freeapply_status (whether FreeApply can run), it holds the facts about the user. Use it once per session, or once per helper, before scoring jobs or filling in a form. With the résumé text and the user's own words it is the only source of facts about the user: never invent what it doesn't contain. To change settings, use freeapply_update_settings. Behavior: read-only; installation secrets are never included. Parameters: sections limits the reply to what a step needs, e.g. ["profile", "eligibility"] for a form; leave out resume, the largest, when you don't need its text. Default all. Returns: {settings, missing}. Sections: profile, targets, eligibility, resume (file paths, text, profile), cover_letter, automation, autorun, gmail, custom_answers, models, model_choices and sharing (choices only). missing lists required fields still empty as {key, label}; while it isn't empty, don't apply anywhere: open the settings tab with freeapply_open_dashboard and ask the user to fill them. Errors: an unknown section name; the message lists the valid ones.

NameRequiredDescriptionDefault
sectionsNoSections to return. Optional; default all.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only/idempotent/non-destructive, yet the description still adds value beyond them: installation secrets are never included, the return shape is {settings, missing}, and `missing` acts as a blocking precondition. It also discloses the error case (unknown section name, message lists valid ones) and a guardrail against fabricating user facts.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then labeled Behavior/Parameters/Returns/Errors, and nearly every sentence carries actionable content. It is, however, a dense paragraph with deeply nested parentheticals (the long section enumeration) that would scan faster as a list; slight tightening is possible without losing information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and only one optional parameter, the description compensates fully: it enumerates the returned sections and their contents, explains `missing`, describes the error path, and states the session-level calling convention. Nothing an agent needs to invoke or interpret the result is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline would be 3, but the description adds real meaning: `sections` narrows the reply to what a step needs, is illustrated with a concrete example (["profile", "eligibility"] for a form), defaults to all, and warns that resume is the largest and should be omitted when its text isn't needed — a cost hint the schema lacks.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ("Reads the user's settings") and immediately scopes it: identity, targets, and FreeApply behavior. It explicitly names the two nearest siblings (freeapply_user_answers and freeapply_status) and states how this differs from each, so an agent can select it 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.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete when-to-use ("once per session, or once per helper, before scoring jobs or filling in a form") plus the exclusion and alternative ("To change settings, use freeapply_update_settings"). It also adds a gated follow-up path: while `missing` is non-empty, open the dashboard and ask the user, rather than proceeding.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeapply_job_statsGet job-search statisticsA
Read-onlyIdempotent

Summarizes the user's job search in numbers: applications, replies, interviews, offers and rates. Unlike freeapply_list_jobs (individual jobs) and freeapply_status (whether FreeApply can run), it gives totals. Use it to report progress, for example when wrapping up a session. Not for finding a particular job. Behavior: read-only and cheap: counted fresh from the local database on each call, nothing cached. Takes no parameters. Returns: tracked, applied, applied_today, queued, needs_you (jobs waiting on the user), interviews, offers, rejections, acknowledged, response_rate (percent of applications with a real reply, automatic acknowledgements not counted), avg_fit, last_reply_check (when the last Gmail reply check finished), counts by_status, by_outcome and by_method, daily (applications per day), and top_companies, top_titles and top_jobs.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Although annotations already declare readOnlyHint, idempotentHint and openWorldHint=false, the description adds genuinely non-redundant behavior: counts are computed fresh from the local database on every call with no caching, and the tool takes no parameters. It also clarifies a non-obvious semantic ('response_rate' counts only real replies, not automatic acknowledgements) and defines 'needs_you' and 'last_reply_check'.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The text is front-loaded with purpose and disambiguation before the behavior and return-value blocks, and each section is scannable. The long enumeration of return fields is justified because no output schema exists, though it is dense and could be grouped more tightly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description carries the burden of describing returns, and it does so exhaustively across scalars, rate definitions, by_status/by_outcome/by_method groupings, daily series, and top_companies/top_titles/top_jobs. Combined with the read-only annotation profile, an agent has everything needed to call and interpret this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With zero parameters, the baseline is 4, and the description does confirm 'Takes no parameters', removing any ambiguity about whether filters or date ranges exist. There is no further parameter meaning to convey, so it cannot exceed the baseline meaningfully.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Summarizes the user's job search in numbers', then enumerates the concrete metrics (applications, replies, interviews, offers, rates). It explicitly distinguishes itself from freeapply_list_jobs (individual jobs) and freeapply_status (whether FreeApply can run), so an agent can route correctly 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.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives both a positive trigger ('Use it to report progress, for example when wrapping up a session') and a negative exclusion ('Not for finding a particular job'), plus named alternatives for the excluded case. Nothing about when to choose this tool 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.

freeapply_list_jobsList tracked jobsA
Read-onlyIdempotent

Lists the user's tracked jobs, most recent activity first (submitted, else updated, else found). Unlike freeapply_job_stats, which gives totals and rates, it returns the jobs themselves. Use it to find a job_id or to answer questions about particular jobs. Not for adding or changing jobs; that is freeapply_claim_job and freeapply_update_job. Behavior: read-only. Parameters: filters combine. status and outcome match exactly; search finds text in the title, company or location, ignoring case. limit (default 200, at most 2000) and offset (default 0) page through long lists: fewer jobs than limit means the end. Returns: a list of jobs, each with id, title, company, location, work_mode, pay_text, pay_min, pay_max, url, apply_url, fit_score, status, status_note, outcome, outcome_at, source, found_at, updated_at, method, submitted_at, confirmation, resume_path, cover_path and reply_count; empty when nothing matched.

NameRequiredDescriptionDefault
limitNoMost jobs to return. Optional; default 200.
offsetNoJobs to skip, for the next page. Optional; default 0.
searchNoText to find in the title, company or location. Optional.
statusNoOnly jobs with this status. Optional.
outcomeNoOnly jobs with this employer outcome. Optional.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as read-only, idempotent, non-destructive, and closed-world. The description adds useful behavioral detail beyond that: sorting order, exact-match filters, case-insensitive search, pagination behavior, and end-of-list detection.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose and alternatives, then moves efficiently through behavior, parameters, and returns. The return-field list is long but justified because there is no output schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and five optional parameters, the description supplies the missing context: use cases, sibling alternatives, filtering semantics, pagination behavior, and returned fields. An agent has enough information 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.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents each parameter. The description still adds meaning by explaining that filters combine, status and outcome match exactly, search covers title/company/location ignoring case, and pagination works through limit and offset.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: it lists the user's tracked jobs. It explicitly distinguishes itself from freeapply_job_stats by explaining that it returns the jobs themselves rather than totals and rates.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit use cases: find a job_id or answer questions about particular jobs. It also states what it is not for, pointing adding or changing jobs to freeapply_claim_job and freeapply_update_job.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeapply_open_dashboardOpen the dashboard in the browserA
Read-onlyIdempotent

Opens the user's local FreeApply dashboard in their browser, on one tab. Unlike freeapply_status, which only reports its address, it puts the page in front of the user. Use it when the user has to act there: accept the Terms, fill in settings, answer questions waiting on them, or review applications and replies. Not for reading data; the other tools give you the same information. Behavior: changes no data. Starts the dashboard if needed, on http://127.0.0.1:7878 or the next free port; only this computer can reach it. Parameters: tab picks the page: overview (the Terms show there until accepted), settings (the setup fields), issues (the Needs you list of questions and sign-ups), applications or replies. Default overview. Returns: {url, opened}. url null: the dashboard couldn't start (no free port); tell the user. opened false with a url: no browser could be launched; give the user the url.

NameRequiredDescriptionDefault
tabNoThe page to open. Optional; default overview.

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish read-only, idempotent, non-destructive, non-open-world behavior. The description adds useful context beyond that: it starts the dashboard if needed, uses localhost on port 7878 or the next free port, is reachable only from this computer, and changes no data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the action and the sibling distinction, then cleanly sections usage, behavior, parameters, and returns. Despite its length, every section carries operational value for correct invocation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, but the description explains the {url, opened} return shape and both failure modes: null url when the dashboard cannot start, and false opened with a url when no browser could be launched. That is enough for an agent to act correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema documents the tab parameter and enum values, but the description adds meaningful semantics for each tab: overview shows Terms until accepted, settings shows setup fields, issues shows the Needs list, and applications/replies are review tabs. This materially improves selection beyond the raw enum names.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: opening the user's local FreeApply dashboard in their browser. It explicitly distinguishes itself from freeapply_status, which only reports the address, so the agent can choose between them without inspecting schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-to-use guidance: when the user must accept Terms, fill settings, answer waiting questions, or review applications and replies. It also gives a clear when-not-to-use rule: not for reading data because other tools provide the same information.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeapply_record_outcomeRecord what an employer didA
Idempotent

Records what an employer did with an application: acknowledged, replied, assessment, interview, rejected or offer. Unlike freeapply_update_job, which records your side (applied, skipped, ...), it is about the employer's response. Use it for each employer email found during a reply check, between freeapply_reply_check start and finish, and when the user tells you about a call or corrects an outcome. Not for your own steps. Behavior: with an email (gmail_message_id) it stores the email and raises the job's outcome only if this email ranks higher than the current one (an interview outranks an acknowledgement); the same gmail_message_id again stores nothing new. Without an email it sets the outcome exactly, whatever its rank, and an empty outcome clears it. Parameters: outcome is required; "" clears it, without an email only. job_id, from the reply-check plan or freeapply_list_jobs, is required without an email; with an email it is optional, but then no outcome changes. The email fields fill the dashboard's Replies tab: gmail_thread_id, company, sender, subject, received_at (ISO 8601), summary (at most 20 words, no personal data beyond what is needed) and mail_action (starred, labeled:, starred+labeled: or none). Returns: with an email {recorded, kind, job_id, outcome}, where outcome is the job's outcome afterwards and both are null without job_id; without one {job_id, outcome}. Errors: an unknown job_id, no job_id and no email, or an empty outcome with an email.

NameRequiredDescriptionDefault
job_idNoThe job it is about.
senderNoWith an email: sender address.
companyNoWith an email: the employer that sent it.
outcomeYesWhat the employer did: acknowledged (automatic 'we received your application' email), replied (a person replied), assessment (test, assignment or screening questionnaire), interview (interview requested or scheduled), rejected (rejection), offer (offer), withdrawn (candidate withdrew); or "" to clear it.
subjectNoWith an email: subject line.
summaryNoWith an email: one sentence on what it says.
mail_actionNoWith an email: what you did with it in Gmail.
received_atNoWith an email: when it arrived (ISO 8601).
gmail_thread_idNoWith an email: Gmail thread id.
gmail_message_idNoThe employer email's Gmail message id.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well past the annotations: it discloses the rank-based raise-only rule with an email, exact-set semantics without one, deduplication of a repeated gmail_message_id, the clearing behavior of an empty outcome, and enumerated error conditions. It is consistent with idempotentHint=true and non-destructive framing.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads purpose, then behavior, parameters, returns, and errors in a predictable order with no filler sentences. It is dense and long, but nearly every clause carries conditional or semantic information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 10-parameter mutation tool with no output schema, it supplies the return shapes for both branches and the error cases, so an agent can call it and interpret the result without inference. Nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, but the description adds conditional logic the schema cannot express: job_id is required without an email but optional (and outcome-inert) with one, and empty outcome is only valid without an email. It also supplies the mail_action value vocabulary and a 20-word/no-PII constraint on summary that the schema omits.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('Records what an employer did with an application') and enumerates the exact outcome space. It explicitly contrasts with freeapply_update_job (employer's response vs. your own side), making it distinguishable from the closest sibling 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.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

States concrete triggers (each employer email found during a reply check, between freeapply_reply_check start and finish, when the user reports a call or corrects an outcome) and an explicit exclusion ('Not for your own steps'), pointing at the sibling that covers that case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeapply_reply_checkStart or finish a Gmail reply checkA
Idempotent

Begins and ends a Gmail reply check (the freeapply-replies procedure). Unlike freeapply_record_outcome, which records each email, it frames the check: start gives the plan, finish marks it done. Use start before searching Gmail and finish once every email you found is recorded. Not for recording an email. Behavior: start is read-only and can be repeated. finish sets the last check to now, so the next check searches only newer email: call it only after recording everything you found. Parameters: action start returns the plan: since (search Gmail from this time), gmail (the user's mail action: none, star, label or star_and_label, plus label_name), applied (the jobs applied to: job_id, company, title, submitted_at) and known_message_ids (already recorded: skip them). action finish marks the check done. Returns: start: the plan above. finish: {last_check}. Errors: another action.

NameRequiredDescriptionDefault
actionYesstart returns the plan; finish marks the check done.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds substantial behavior beyond the annotations: start is read-only and repeatable, while finish sets the last check time and changes what the next check searches. It also warns to call finish only after recording everything found, which is important operational context not captured by the schema or annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded and organized into purpose, usage, behavior, parameters, returns, and errors. It is somewhat repetitive in restating start/finish behavior across sections, but the repetition reinforces a short two-action workflow rather than adding noise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter workflow tool with no output schema, the description covers the missing return-value information directly, including the plan returned by start and {last_check} returned by finish. It also explains the key side effect of finish and the error case, leaving no important gap for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the enum already documents start/finish, but the description goes further by explaining what start returns: since, gmail, applied, and known_message_ids. It adds meaningful semantics for the action parameter beyond the schema, though the parameter itself is simple.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb+resource+workflow framing: it begins/ends a Gmail reply check and explicitly distinguishes this framing role from freeapply_record_outcome, which records individual emails. An agent can tell exactly what the tool is for and what it is not for.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit ordering and conditions: use start before searching Gmail, use finish only after every found email is recorded, and do not use this tool for recording an email. It also names the sibling alternative freeapply_record_outcome, so the routing decision is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeapply_report_site_problemReport a job site signed out or limitedA
DestructiveIdempotent

Tells FreeApply that one of the user's job sites can't be used right now: it signed the user out, or showed its own daily limit. Unlike freeapply_find_site_account, which is about an employer's own careers site, it is for the job sites the user chose in Settings, such as LinkedIn or Indeed. Use it as soon as a chosen job site shows a sign-in page or a daily limit, then keep applying on the ready sites or on company career sites. Never type a password. Behavior: a signed-out site stays unavailable until the user signs in again and confirms it in the dashboard; a limited site is paused until midnight. Meanwhile freeapply_claim_job refuses new jobs from it. Reporting the same problem again changes nothing, and only the user can mark a site ready. Parameters: site is the job site's id as freeapply_status lists it in sites. status is signed_out (a sign-in page, or the site says you're signed out) or limit_reached (the site's own daily limit, e.g. "You reached today's Easy Apply limit"). Returns: {site, status, sites}, where sites lists each chosen site with ready. Errors: a site the user didn't choose.

NameRequiredDescriptionDefault
siteYesThe job site, as listed in freeapply_status sites.
statusYesWhat the site showed.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well past the annotations: describes the downstream effect on freeapply_claim_job (refuses new jobs from the reported site), the duration of each state (signed-out until user re-confirms in dashboard; limit paused until midnight), idempotency in plain terms ('reporting the same problem again changes nothing'), and who can reverse it ('only the user can mark a site ready'). This explains the destructiveHint consequence better than the annotation alone does.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose and the sibling contrast, then organized into Behavior / Parameters / Returns / Errors blocks. Dense but every line carries information; the Returns and Errors lines could be folded in more tightly, but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description supplies the return shape ({site, status, sites} with ready flags) and an error case (a site the user didn't choose). Combined with the state/pause semantics, an agent has everything needed to call it and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both params are enums, so the baseline is 3; the description adds real meaning by interpreting each status value with examples ('a sign-in page', '"You reached today's Easy Apply limit"') and by tying site to the ids listed in freeapply_status. Slight over-reliance on the schema for the site enumeration itself.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (tells FreeApply a chosen job site can't be used, signed out or limit reached) and explicitly contrasts itself with the sibling freeapply_find_site_account (employer careers site vs. user-chosen sites like LinkedIn/Indeed). An agent can route between the two without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete trigger ('as soon as a chosen job site shows a sign-in page or a daily limit'), a fallback plan ('keep applying on the ready sites or on company career sites'), and a hard exclusion ('never type a password'). The distinction from freeapply_find_site_account is spelled out rather than implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeapply_shared_dataPreview or send shared dataA
Idempotent

Shows or sends the data the user chose to share with the FreeApply server. Unlike freeapply_get_settings, which shows the sharing choices, it shows the exact data those choices send. Use preview when the user asks what is shared, and sync only when the user asks to send now; it also runs on its own every 12 hours. Not for changing the choices: the user does that in the dashboard (Settings, Data sharing). Behavior: preview is read-only and sends nothing. sync sends over the internet only what the current choices allow and can't be undone from here; the user can delete their shared data in the dashboard. Parameters: action preview is safe to call any time; action sync sends now and is refused moments after the last sync. Returns: preview: the exact requests that would be sent: analytics_request (anonymous usage and job-market data) and the talent-pool request, only if the user joined, secrets hidden. sync: {sent, result}, or {sent: false, reason}: the Terms not accepted, a sync moments ago, or the server unreachable (the automatic sync retries later). Errors: another action.

NameRequiredDescriptionDefault
actionYespreview shows what would be sent; sync sends it now.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well past the annotations: preview is read-only and sends nothing, sync reaches the internet and cannot be undone from here, it also fires automatically every 12 hours, and sync is refused moments after the last sync. Return shapes and failure reasons (Terms not accepted, recent sync, server unreachable) are spelled out, consistent with openWorldHint=true and destructiveHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then labeled Behavior/Parameters/Returns/Errors sections that make scanning easy. Slightly redundant: the preview-vs-sync distinction is restated in the Parameters block after already appearing in the usage paragraph.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, yet the description documents both return shapes (analytics_request and talent-pool request for preview; {sent, result} or {sent: false, reason} for sync) and enumerates the refusal reasons. For a one-parameter tool with a network side effect, nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the enum already names both values, so the baseline is 3. The description adds real per-value semantics — preview safe any time, sync sends now and may be rejected right after a prior sync — rather than restating the enum.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb pair (shows/preview vs sends/sync) and the exact resource (the data the user chose to share with the FreeApply server). It explicitly distinguishes itself from the nearest sibling, freeapply_get_settings: choices vs. the exact data those choices send.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a direct routing rule — 'Use preview when the user asks what is shared, and sync only when the user asks to send now' — plus an exclusion ('Not for changing the choices: the user does that in the dashboard') and an alternative surface (Settings, Data sharing). 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.

freeapply_statusCheck FreeApply and get a procedureA
Read-onlyIdempotent

Reports whether FreeApply can work now and returns the signed step-by-step procedure for a task. Unlike freeapply_get_settings (the user's details) and freeapply_job_stats (the job search), it is about FreeApply itself. Use it first in every session and before each task; call it again only to re-check after the user acts. It works while FreeApply is locked or the Terms aren't accepted, so it can tell you why. Behavior: changes no user data. Sets up the data folder on first run, starts the local dashboard if needed and refreshes the résumé copy in the documents folder. Parameters: procedure adds that task's text: freeapply-setup (first run, or Terms or settings missing), freeapply-apply (find jobs and apply) or freeapply-replies (Gmail reply check). Omit it for the status alone. Returns: workflow {ok, problem}, terms {ok}, setup_complete, missing, sites (each chosen job site with ready), autorun, update, dashboard (its URL), data_dir, documents {dir, resume, cover_letters}, stats, procedures, and models {can_delegate, rescan, levels, lanes, unfilled}: each level and lane gives {model, effort, source}, and model current means your own model does it. With procedure also procedure {name, description, text, workflow_version, workflow_hash}, null while locked. Next: workflow.ok false: tell the user why and stop. terms.ok or setup_complete false: follow freeapply-setup. models.rescan true: do its AI models step first.

NameRequiredDescriptionDefault
procedureNoThe task whose procedure to include. Optional.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the readOnly/idempotent/non-destructive annotations by disclosing side effects an agent would otherwise not expect: creating the data folder on first run, starting the local dashboard, and refreshing the résumé copy. It also documents the failure semantics (works while locked, reports why) rather than hiding them. Only mild tension exists between readOnlyHint and those setup side effects, but the description surfaces them openly rather than concealing them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well front-loaded — purpose first, then sibling contrast, then usage, then Behavior/Parameters/Returns/Next sections, making it easy to scan. It is on the long side, though: the full enumeration of models {can_delegate, rescan, levels, lanes, unfilled} and per-lane {model, effort, source} is heavier detail than most invocations need.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description compensates by enumerating the returned fields, calling out the conditional procedure payload and its null-while-locked behavior, and giving error-handling next steps. For a status-plus-procedure gate tool with 17 siblings, nothing an agent needs in order 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.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100% with an enum, yet the description adds selection logic the enum values alone do not convey: freeapply-setup for first run or missing Terms/settings, freeapply-apply for finding and applying to jobs, freeapply-replies for the Gmail reply check, and 'omit it for the status alone'. This is real added meaning over the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Reports whether FreeApply can work now and returns the signed step-by-step procedure for a task') and explicitly distinguishes itself from the two nearest siblings: freeapply_get_settings (user details) and freeapply_job_stats (job search). An agent can route to it 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.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit timing rules ('Use it first in every session and before each task; call it again only to re-check after the user acts'), an edge-case guarantee (works while locked or Terms not accepted), and concrete branching in 'Next' for workflow.ok false and terms.ok/setup_complete false. Both when-to-use and what-to-do-next are spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeapply_update_jobUpdate a job's application statusA
DestructiveIdempotent

Records your side of an application by setting a tracked job's status. Unlike freeapply_record_outcome (what the employer did) and freeapply_claim_job (adding a job), it changes a job you already claimed. Use it after a submit (applied), when you give up on a job (skipped or failed), and when the user must act: needs_info with the form's questions, needs_account with the sign-up page, blocked by a check you can't pass. Not for employer replies. Behavior: replaces the job's status. Enforced: applied needs a fresh clearance from freeapply_clear_to_submit for this job; cover_text must pass the truthfulness check; a job already applied to only the user can change. needs_info questions go to the Needs you tab and re-queue the job once answered; if the user already answered them all, the call is refused with the answers to use. Parameters: note is one plain sentence the user reads, with no technical terms. Some fields go with one status and are refused with any other: questions (at least one) with needs_info; account_url with needs_account; method, confirmation, resume_path, cover_path and cover_text with applied. The résumé copy and the letter saved by freeapply_check_text are recorded by default; pass the file and letter fields only when you sent something else. Returns: {job_id, status}, and when relevant: already_waiting; questions (each added, duplicate, grouped or already_answered, with its answer) and questions_added; same_account (needs_account: jobs sharing one sign-up card); same_site (blocked: jobs blocked on the same site). Errors: an unknown job_id or a broken rule, saying what is missing.

NameRequiredDescriptionDefault
noteNoWhat happened, for the user, e.g. "The site asked to prove you're a person."
job_idYesThe job's id, as returned by freeapply_claim_job or freeapply_list_jobs.
methodNoFor applied: how it was submitted.
statusYesNew status: found (qualified, not yet worked), ready (documents prepared, not yet submitted), applied (application submitted), skipped (filtered out (see status_note)), needs_info (a form asked something the profile does not answer), needs_account (employer site requires creating an account), blocked (CAPTCHA, verification code or site warning), failed (error while applying).
questionsNoFor needs_info: the form's unanswered questions, each with a plain prompt and the simplest kind of answer that fits.
cover_pathNoFor applied: the cover-letter file sent, if not the saved one. Optional.
cover_textNoFor applied: the cover letter sent, if not the saved one. Optional.
account_urlNoFor needs_account: the site's sign-up page. Jobs with the same one share a card, and one "I made the account" re-queues them all; without it the application link is used, so jobs rarely share.
resume_pathNoFor applied: the résumé file sent, if not the documents copy. Optional.
confirmationNoFor applied: the confirmation text or number the site showed.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes far beyond the annotations (destructive, idempotent, non-read-only) by disclosing enforcement rules: applied requires fresh clearance from freeapply_clear_to_submit, cover_text passes truthfulness check, only the user can change an already-applied job, needs_info re-queues the job, and a refusal returns answers when all questions were already answered. These are behavioral traits an agent cannot infer from annotations alone, and none contradict them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is long but tightly structured with labeled sections (Behavior, Parameters, Returns, Errors) and the purpose is front-loaded. Nearly every sentence carries actionable information, though the density could be trimmed slightly without loss.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 10 parameters and no output schema, the description fills the gap by documenting the return shape ({job_id, status}, already_waiting, questions, same_account, same_site) and error behavior. Together with parameter and behavior sections, an agent has everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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, but the description adds meaningful conditional semantics: which fields pair with which status and are otherwise refused, and that résumé/letter defaults are recorded unless overridden. It also clarifies that 'note' is one plain sentence for the user. This is real value beyond the schema, though some of the field-status coupling is already present in the schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Records your side of an application by setting a tracked job's status') and explicitly distinguishes itself from freeapply_record_outcome (employer side) and freeapply_claim_job (adding a job). An agent can identify this as the status-mutation tool 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.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names when to use it: after a submit (applied), when giving up (skipped/failed), and when the user must act (needs_info, needs_account, blocked), plus a clear exclusion ('Not for employer replies'). The status triggers function as concrete invocation guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeapply_update_settingsSave settings and résuméA
DestructiveIdempotent

Saves what the user told you, what setup reads from their résumé, and the AI models scan. Unlike freeapply_user_answers, which keeps answers to single form questions, it changes the settings themselves. Use it when the user states a fact or preference, in setup to store the résumé's text and profile, and in the AI models step. Don't fill a field the user didn't give you; to read settings, use freeapply_get_settings. Behavior: overwrites the fields you send, with no undo. patch is deep-merged: only its fields change, nested objects merge, lists are replaced whole. Sections only the user changes in the dashboard (legal, sharing, automation, autorun, onboarding, integrity, model_choices) are skipped and listed in ignored. All or nothing: if any field is wrong, nothing is saved. Parameters: patch is nested by section with freeapply_get_settings' field names, e.g. {"targets": {"min_pay": 60000}}. resume takes only text and profile ({headline, skills, titles, education, certifications}, from the résumé text alone). models is the scan {app, current, can_delegate, available, efforts}, read from your own tools; it replaces the last scan. Returns: {changed, ignored, setup_complete, missing}; after a scan also models, the model and effort chosen for each level. Errors: nothing writable, an unknown section or field, a wrong type, a value outside its choices (e.g. cover_letter.length is short, standard or long), résumé files (the user adds those in the dashboard) or a malformed scan. The message names every problem.

NameRequiredDescriptionDefault
patchYesThe fields to change, nested by section, e.g. {"profile": {"phone": "+1 555 0100"}}.

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already mark the tool as destructive and non-read-only, but the description adds crucial behavior: fields are overwritten with no undo, patch is deep-merged, lists are replaced wholesale, dashboard-only sections are skipped and returned in ignored, and the operation is all-or-nothing. It also describes return fields and error cases, giving the agent a full operational picture beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Despite its length, the description is front-loaded with purpose, then usage, behavior, parameter details, returns, and errors. Each section carries distinct, necessary information for a complex write operation, and no sentence is redundant filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex mutation tool with no output schema, the description covers when to use it, how merging and skipping work, all-or-nothing behavior, return shape, and error conditions. It gives the agent everything needed to invoke the tool correctly and interpret its results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but the description still adds substantial meaning: patch is nested by section using freeapply_get_settings field names, with a concrete example. It further explains resume's text/profile shape and models' scan shape, including that models replaces the last scan. This goes well beyond the schema's generic patch description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses specific verbs and resources: saving settings, résumé setup data, and AI model scan data. It explicitly distinguishes itself from freeapply_user_answers by saying it changes settings themselves rather than single-question answers. An agent can identify the tool's purpose and boundary against siblings 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.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit usage conditions: when the user states a fact or preference, during setup to store résumé text/profile, and in the AI models step. It also gives exclusions and alternatives: do not fill fields the user did not provide, and use freeapply_get_settings to read settings. This is clear when-to-use and when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

freeapply_user_answersGet or save the user's answersA
DestructiveIdempotent

Gets or saves the user's own answers to application questions, so you never guess one. Unlike freeapply_get_settings (the user's general details) it holds answers to specific form questions, and unlike freeapply_update_job status needs_info it asks the user nothing new. Use get before retrying a job the user re-queued from the Needs you tab, and save when the user answers a question in this conversation, so later forms can reuse it. Save only the user's own words: saved answers count as facts in freeapply_check_text. Behavior: get is read-only. save replaces an answer saved under the same question; an empty answer removes it. Parameters: action get needs job_id. action save needs label, the question as forms word it (e.g. "Are you willing to relocate?"), and answer, the user's words. Returns: get {job_id, answers, saved_answers}: answers are the {label, answer} pairs the user gave for that job (empty when none), saved_answers maps questions to reusable answers. save {label, saved, removed, saved_answers}. Errors: get without job_id or with an unknown one, save without label, or another action.

NameRequiredDescriptionDefault
labelNoFor save: the question, worded as forms ask it, e.g. "Are you willing to relocate?".
actionYesget a job's answers, or save one reusable answer.
answerNoFor save: the user's answer in their own words; empty to remove a saved answer.
job_idNoFor get: the job whose answers you need.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare destructiveHint=true but say nothing about what is destroyed; the description fills that gap by stating that save replaces an answer under the same question and that an empty answer removes it, plus that get is read-only. It also warns that saved answers count as facts in freeapply_check_text, which is non-obvious downstream behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and sibling contrast, then organized under Behavior, Parameters, Returns and Errors headings, which makes it easy to scan. It is longer than strictly necessary because the Parameters section restates schema content, but nearly every sentence carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description supplies return shapes for both actions (answers vs saved_answers for get, label/saved/removed for save) and enumerates error conditions. For a dual-action tool with conditional parameters, nothing an agent needs in order 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.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already documents each parameter including the label example, so the description's 'Parameters:' recap is largely duplicative. It adds only marginal semantics, namely that the answer should be 'the user's own words' and that an empty answer is the removal mechanism.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb pair and resource ('Gets or saves the user's own answers to application questions') and explicitly contrasts itself with freeapply_get_settings (general details) and freeapply_update_job status needs_info, so an agent can distinguish it from siblings 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.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete triggers: use get before retrying a job the user re-queued from the Needs you tab, and save when the user answers a question in this conversation. It also names the two nearest alternatives and states what differs, which is exactly the when/when-not/alternatives pattern.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 26 tool updatesv1.0.2
    • Removedfreeapply_add_job
    • Removedfreeapply_answers
    • Changedfreeapply_autorun4 fields changed
      • changedInput schema / properties / action / description
        Previous value: -"What to do."New value: +"start or finish a run, or report the scheduled task."
      • changedInput schema / properties / action / enum
        Previous value: -[
        -  "start",
        -  "check",
        -  "finish",
        -  "schedule_created",
        -  "schedule_removed"
        -]New value: +[
        +  "start",
        +  "finish",
        +  "schedule_created",
        +  "schedule_removed"
        +]
      • changedInput schema / properties / run_id / description
        Previous value: -"The run_id that start returned; needed for check and finish."New value: +"For finish: the run_id that start returned."
      • changedInput schema / properties / summary / description
        Previous value: -"One-line summary, for finish."New value: +"For finish: one line on the run."
    • Removedfreeapply_check_duplicate
    • Changedfreeapply_check_text4 fields changed
      • changedInput schema / properties / company / description
        Previous value: -"The employer it is addressed to. Optional; a cover letter that never mentions it is flagged."New value: +"The employer, when there is no job_id. Optional."
      • changedInput schema / properties / job_id / description
        Previous value: -"The job it is for. Optional; numbers from its posting and the user's answers for it then count as supported."New value: +"The job it is for. Optional; needed for save."
      • addedInput schema / properties / save
        Added value: +{
        +  "description": "Save a passing cover letter as a PDF. Optional; default false.",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / text / description
        Previous value: -"The cover letter or answer to check."New value: +"The cover letter or answer to check, exactly as you will type or attach it."
    • Addedfreeapply_claim_job
    • Addedfreeapply_clear_to_submit
    • Changedfreeapply_fetch_posting1 field changed
      • changedInput schema / properties / source / description
        Previous value: -"Where the posting was found, as a job site id (linkedin, indeed, company_sites, ...). Optional; helps pick suggested answers."New value: +"The job site id where it was found. Optional."
    • Addedfreeapply_find_site_account
    • Changedfreeapply_get_settings1 field changed
      • addedInput schema / properties / sections
        Added value: +{
        +  "description": "Sections to return. Optional; default all.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
    • Removedfreeapply_get_stats
    • Addedfreeapply_job_stats
    • Changedfreeapply_open_dashboard1 field changed
      • changedInput schema / properties / tab / description
        Previous value: -"Tab to show. Optional; default overview."New value: +"The page to open. Optional; default overview."
    • Addedfreeapply_record_outcome
    • Removedfreeapply_record_reply
    • Addedfreeapply_report_site_problem
    • Removedfreeapply_save_resume
    • Removedfreeapply_set_outcome
    • Removedfreeapply_site_account
    • Removedfreeapply_site_status
    • Changedfreeapply_status1 field changed
      • addedInput schema / properties / procedure
        Added value: +{
        +  "description": "The task whose procedure to include. Optional.",
        +  "enum": [
        +    "freeapply-setup",
        +    "freeapply-apply",
        +    "freeapply-replies"
        +  ],
        +  "type": "string"
        +}
    • Removedfreeapply_throttle
    • Changedfreeapply_update_job10 fields changed
      • changedInput schema / properties / account_url / description
        Previous value: -"For needs_account: the full link to the page where the user makes the account (the site's sign-up page). Jobs whose account is made at the same address share one card, and one \"I made the account\" re-queues them all; without it the application link is used, so jobs rarely share."New value: +"For needs_account: the site's sign-up page. Jobs with the same one share a card, and one \"I made the account\" re-queues them all; without it the application link is used, so jobs rarely share."
      • changedInput schema / properties / confirmation / description
        Previous value: -"Confirmation text or number the site showed."New value: +"For applied: the confirmation text or number the site showed."
      • changedInput schema / properties / cover_path / description
        Previous value: -"Path of the cover-letter file submitted."New value: +"For applied: the cover-letter file sent, if not the saved one. Optional."
      • changedInput schema / properties / cover_text / description
        Previous value: -"The cover letter actually submitted; it must pass the truthfulness check."New value: +"For applied: the cover letter sent, if not the saved one. Optional."
      • changedInput schema / properties / job_id / description
        Previous value: -"The job's id, as returned by freeapply_add_job or freeapply_list_jobs."New value: +"The job's id, as returned by freeapply_claim_job or freeapply_list_jobs."
      • changedInput schema / properties / method / description
        Previous value: -"How it was submitted, for applied."New value: +"For applied: how it was submitted."
      • changedInput schema / properties / note / description
        Previous value: -"What happened, in one plain sentence the user will read on the dashboard: no code, page elements or technical terms, e.g. \"The site asked to prove you're a person.\""New value: +"What happened, for the user, e.g. \"The site asked to prove you're a person.\""
      • changedInput schema / properties / questions / description
        Previous value: -"For needs_info: the form's unanswered questions. Give each a plain prompt and the simplest kind of answer that fits: a choice with options (or yesno) when the form offers fixed answers, multi when it takes several, text otherwise."New value: +"For needs_info: the form's unanswered questions, each with a plain prompt and the simplest kind of answer that fits."
      • changedInput schema / properties / questions / items / properties / type / description
        Previous value: -"Kind of answer: text or textarea (open-ended, short or long), yesno, choice (pick one; buttons for up to 5 options, a dropdown for more), multi (pick all that apply), number or date."New value: +"Kind of answer: yesno or choice for fixed answers (one; buttons up to 5 options, a dropdown for more), multi (all that apply), number, date, or text or textarea."
      • changedInput schema / properties / resume_path / description
        Previous value: -"Path of the résumé file submitted."New value: +"For applied: the résumé file sent, if not the documents copy. Optional."
    • Changedfreeapply_update_settings1 field changed
      • changedInput schema / properties / patch / description
        Previous value: -"The fields to change, nested by section, e.g. {\"targets\": {\"min_pay\": 60000, \"locations\": [\"Denver, CO\"]}} or {\"profile\": {\"phone\": \"+1 555 0100\"}}. Field names are as freeapply_get_settings returns them."New value: +"The fields to change, nested by section, e.g. {\"profile\": {\"phone\": \"+1 555 0100\"}}."
    • Addedfreeapply_user_answers
    • Removedfreeapply_workflow
  2. 26 tool updatesv1.0.1
    • Changedfreeapply_add_job19 fields changed
      • addedInput schema / properties / apply_url / description
        Added value: +"Where the application form is, if different."
      • addedInput schema / properties / company / description
        Added value: +"Employer name."
      • addedInput schema / properties / description / description
        Added value: +"Short description or key requirements."
      • changedInput schema / properties / external_id / description
        Previous value: -"posting id on the source site"New value: +"The posting's id on its source site, used to spot reposts."
      • addedInput schema / properties / fit_notes / description
        Added value: +"Why it fits or doesn't, in a sentence."
      • addedInput schema / properties / fit_score / description
        Added value: +"Fit from 0 to 100, as the procedure describes."
      • addedInput schema / properties / fit_score / maximum
        Added value: +100
      • addedInput schema / properties / fit_score / minimum
        Added value: +0
      • addedInput schema / properties / location / description
        Added value: +"Location as posted."
      • addedInput schema / properties / pay_max / description
        Added value: +"Highest posted pay as a number."
      • addedInput schema / properties / pay_min / description
        Added value: +"Lowest posted pay as a number (annual, or hourly if posted hourly)."
      • addedInput schema / properties / pay_text / description
        Added value: +"Pay exactly as posted, e.g. \"$90k-$110k\"."
      • changedInput schema / properties / source / description
        Previous value: -"linkedin, company_site, indeed, referral, ..."New value: +"Where it was found: a job site id (linkedin, indeed, company_sites, ...) or referral."
      • addedInput schema / properties / status / description
        Added value: +"found to work on it (default), skipped to record a job that doesn't fit."
      • addedInput schema / properties / status / enum
        Added value: +[
        +  "found",
        +  "skipped"
        +]
      • addedInput schema / properties / status_note / description
        Added value: +"Reason, for a skipped job."
      • addedInput schema / properties / title / description
        Added value: +"Job title."
      • addedInput schema / properties / url / description
        Added value: +"The posting's URL."
      • addedInput schema / properties / work_mode / description
        Added value: +"remote, hybrid or onsite, as posted."
    • Addedfreeapply_answers
    • Changedfreeapply_autorun4 fields changed
      • addedInput schema / properties / action / description
        Added value: +"What to do."
      • addedInput schema / properties / action / enum
        Added value: +[
        +  "start",
        +  "check",
        +  "finish",
        +  "schedule_created",
        +  "schedule_removed"
        +]
      • addedInput schema / properties / run_id / description
        Added value: +"The run_id that start returned; needed for check and finish."
      • addedInput schema / properties / summary / description
        Added value: +"One-line summary, for finish."
    • Changedfreeapply_check_duplicate3 fields changed
      • addedInput schema / properties / company / description
        Added value: +"Employer name as shown in the posting."
      • addedInput schema / properties / external_id / description
        Added value: +"The posting's id on its source site. Optional; also finds the exact posting."
      • addedInput schema / properties / title / description
        Added value: +"Job title. Optional; marks matches with the same title."
    • Changedfreeapply_check_text6 fields changed
      • addedInput schema / properties / company / description
        Added value: +"The employer it is addressed to. Optional; a cover letter that never mentions it is flagged."
      • addedInput schema / properties / job_id / description
        Added value: +"The job it is for. Optional; numbers from its posting and the user's answers for it then count as supported."
      • addedInput schema / properties / job_id / minimum
        Added value: +1
      • addedInput schema / properties / kind / description
        Added value: +"What the text is. Optional; default answer."
      • addedInput schema / properties / kind / enum
        Added value: +[
        +  "cover_letter",
        +  "answer"
        +]
      • addedInput schema / properties / text / description
        Added value: +"The cover letter or answer to check."
    • Changedfreeapply_fetch_posting5 fields changed
      • addedInput schema / properties / max_chars / default
        Added value: +6000
      • addedInput schema / properties / max_chars / description
        Added value: +"Longest description to return, in characters. Optional; default 6000."
      • addedInput schema / properties / max_chars / minimum
        Added value: +500
      • addedInput schema / properties / source / description
        Added value: +"Where the posting was found, as a job site id (linkedin, indeed, company_sites, ...). Optional; helps pick suggested answers."
      • addedInput schema / properties / url / description
        Added value: +"The posting's URL: the job page or its application form."
    • Removedfreeapply_finish_reply_check
    • Removedfreeapply_get_answers
    • Changedfreeapply_list_jobs10 fields changed
      • addedInput schema / properties / limit / default
        Added value: +200
      • addedInput schema / properties / limit / description
        Added value: +"Most jobs to return. Optional; default 200."
      • addedInput schema / properties / limit / maximum
        Added value: +2000
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • addedInput schema / properties / offset
        Added value: +{
        +  "default": 0,
        +  "description": "Jobs to skip, for the next page. Optional; default 0.",
        +  "minimum": 0,
        +  "type": "integer"
        +}
      • addedInput schema / properties / outcome / description
        Added value: +"Only jobs with this employer outcome. Optional."
      • addedInput schema / properties / outcome / enum
        Added value: +[
        +  "acknowledged",
        +  "replied",
        +  "assessment",
        +  "interview",
        +  "rejected",
        +  "offer",
        +  "withdrawn"
        +]
      • addedInput schema / properties / search / description
        Added value: +"Text to find in the title, company or location. Optional."
      • addedInput schema / properties / status / description
        Added value: +"Only jobs with this status. Optional."
      • addedInput schema / properties / status / enum
        Added value: +[
        +  "found",
        +  "ready",
        +  "applied",
        +  "skipped",
        +  "needs_info",
        +  "needs_account",
        +  "blocked",
        +  "failed"
        +]
    • Changedfreeapply_open_dashboard2 fields changed
      • addedInput schema / properties / tab / description
        Added value: +"Tab to show. Optional; default overview."
      • addedInput schema / properties / tab / enum
        Added value: +[
        +  "overview",
        +  "applications",
        +  "replies",
        +  "issues",
        +  "settings"
        +]
    • Removedfreeapply_preview_shared_data
    • Changedfreeapply_record_reply12 fields changed
      • addedInput schema / properties / company / description
        Added value: +"The employer that sent it."
      • addedInput schema / properties / gmail_message_id / description
        Added value: +"Gmail message id; prevents recording it twice."
      • addedInput schema / properties / gmail_thread_id / description
        Added value: +"Gmail thread id."
      • addedInput schema / properties / job_id / description
        Added value: +"The job the email is about. Optional, but without it no outcome changes."
      • addedInput schema / properties / job_id / minimum
        Added value: +1
      • addedInput schema / properties / kind / description
        Added value: +"What the email is: acknowledged (automatic 'we received your application' email), replied (a person replied), assessment (test, assignment or screening questionnaire), interview (interview requested or scheduled), rejected (rejection), offer (offer), withdrawn (candidate withdrew)."
      • addedInput schema / properties / kind / enum
        Added value: +[
        +  "acknowledged",
        +  "replied",
        +  "assessment",
        +  "interview",
        +  "rejected",
        +  "offer",
        +  "withdrawn"
        +]
      • addedInput schema / properties / mail_action / description
        Added value: +"What you did with it in Gmail: starred, labeled:<name>, starred+labeled:<name> or none."
      • addedInput schema / properties / received_at / description
        Added value: +"When it arrived (ISO 8601)."
      • addedInput schema / properties / sender / description
        Added value: +"Sender address."
      • addedInput schema / properties / subject / description
        Added value: +"Subject line."
      • addedInput schema / properties / summary / description
        Added value: +"One sentence on what the email says (at most 20 words, no personal data beyond what is needed)."
    • Addedfreeapply_reply_check
    • Removedfreeapply_reply_check_plan
    • Addedfreeapply_save_resume
    • Removedfreeapply_save_resume_profile
    • Removedfreeapply_save_resume_text
    • Changedfreeapply_set_outcome4 fields changed
      • addedInput schema / properties / job_id / description
        Added value: +"The job's id, as returned by freeapply_add_job or freeapply_list_jobs."
      • addedInput schema / properties / job_id / minimum
        Added value: +1
      • addedInput schema / properties / outcome / description
        Added value: +"acknowledged (automatic 'we received your application' email), replied (a person replied), assessment (test, assignment or screening questionnaire), interview (interview requested or scheduled), rejected (rejection), offer (offer), withdrawn (candidate withdrew), or \"\" to clear."
      • addedInput schema / properties / outcome / enum
        Added value: +[
        +  "acknowledged",
        +  "replied",
        +  "assessment",
        +  "interview",
        +  "rejected",
        +  "offer",
        +  "withdrawn",
        +  ""
        +]
    • Addedfreeapply_shared_data
    • Changedfreeapply_site_account1 field changed
      • addedInput schema / properties / site / description
        Added value: +"The employer site's domain or any URL on it, e.g. careers.example.com or the application form's URL."
    • Changedfreeapply_site_status4 fields changed
      • changedInput schema / properties / site / description
        Previous value: -"linkedin, indeed, glassdoor, ziprecruiter, dice, wellfound, handshake, company_sites"New value: +"The job site."
      • addedInput schema / properties / site / enum
        Added value: +[
        +  "linkedin",
        +  "indeed",
        +  "glassdoor",
        +  "ziprecruiter",
        +  "dice",
        +  "wellfound",
        +  "handshake",
        +  "company_sites"
        +]
      • addedInput schema / properties / status / description
        Added value: +"What the site showed."
      • addedInput schema / properties / status / enum
        Added value: +[
        +  "signed_out",
        +  "limit_reached"
        +]
    • Removedfreeapply_sync_shared_data
    • Changedfreeapply_throttle4 fields changed
      • addedInput schema / properties / job_id / description
        Added value: +"The job's id, as returned by freeapply_add_job or freeapply_list_jobs."
      • addedInput schema / properties / job_id / minimum
        Added value: +1
      • addedInput schema / properties / method / description
        Added value: +"How you will submit. Optional; default external (an employer or ATS form)."
      • addedInput schema / properties / method / enum
        Added value: +[
        +  "external",
        +  "easy_apply",
        +  "email"
        +]
    • Changedfreeapply_update_job15 fields changed
      • addedInput schema / properties / account_url
        Added value: +{
        +  "description": "For needs_account: the full link to the page where the user makes the account (the site's sign-up page). Jobs whose account is made at the same address share one card, and one \"I made the account\" re-queues them all; without it the application link is used, so jobs rarely share.",
        +  "type": "string"
        +}
      • addedInput schema / properties / confirmation / description
        Added value: +"Confirmation text or number the site showed."
      • addedInput schema / properties / cover_path / description
        Added value: +"Path of the cover-letter file submitted."
      • addedInput schema / properties / cover_text / description
        Added value: +"The cover letter actually submitted; it must pass the truthfulness check."
      • addedInput schema / properties / job_id / description
        Added value: +"The job's id, as returned by freeapply_add_job or freeapply_list_jobs."
      • addedInput schema / properties / job_id / minimum
        Added value: +1
      • addedInput schema / properties / method / description
        Added value: +"How it was submitted, for applied."
      • addedInput schema / properties / method / enum
        Added value: +[
        +  "easy_apply",
        +  "external",
        +  "email"
        +]
      • addedInput schema / properties / note / description
        Added value: +"What happened, in one plain sentence the user will read on the dashboard: no code, page elements or technical terms, e.g. \"The site asked to prove you're a person.\""
      • addedInput schema / properties / questions / description
        Added value: +"For needs_info: the form's unanswered questions. Give each a plain prompt and the simplest kind of answer that fits: a choice with options (or yesno) when the form offers fixed answers, multi when it takes several, text otherwise."
      • addedInput schema / properties / questions / items / properties
        Added value: +{
        +  "help": {
        +    "description": "Optional one-line hint the user sees under the prompt: why it's asked or what a good answer looks like.",
        +    "type": "string"
        +  },
        +  "label": {
        +    "description": "The question exactly as the form words it (you need it to fill the form later).",
        +    "type": "string"
        +  },
        +  "options": {
        +    "description": "Choices, for choice or multi, worded as the form offers them.",
        +    "items": {
        +      "type": "string"
        +    },
        +    "type": "array"
        +  },
        +  "prompt": {
        +    "description": "The question in plain words for the user: one short sentence, no form codes or jargon, e.g. \"Can you work weekends?\" for \"Availability - Sat/Sun shifts (Y/N)*\".",
        +    "type": "string"
        +  },
        +  "required": {
        +    "description": "Whether the form requires it.",
        +    "type": "boolean"
        +  },
        +  "type": {
        +    "description": "Kind of answer: text or textarea (open-ended, short or long), yesno, choice (pick one; buttons for up to 5 options, a dropdown for more), multi (pick all that apply), number or date.",
        +    "enum": [
        +      "text",
        +      "textarea",
        +      "yesno",
        +      "choice",
        +      "multi",
        +      "number",
        +      "date"
        +    ],
        +    "type": "string"
        +  }
        +}
      • addedInput schema / properties / questions / items / required
        Added value: +[
        +  "label"
        +]
      • addedInput schema / properties / resume_path / description
        Added value: +"Path of the résumé file submitted."
      • addedInput schema / properties / status / description
        Added value: +"New status: found (qualified, not yet worked), ready (documents prepared, not yet submitted), applied (application submitted), skipped (filtered out (see status_note)), needs_info (a form asked something the profile does not answer), needs_account (employer site requires creating an account), blocked (CAPTCHA, verification code or site warning), failed (error while applying)."
      • addedInput schema / properties / status / enum
        Added value: +[
        +  "found",
        +  "ready",
        +  "applied",
        +  "skipped",
        +  "needs_info",
        +  "needs_account",
        +  "blocked",
        +  "failed"
        +]
    • Changedfreeapply_update_settings1 field changed
      • addedInput schema / properties / patch / description
        Added value: +"The fields to change, nested by section, e.g. {\"targets\": {\"min_pay\": 60000, \"locations\": [\"Denver, CO\"]}} or {\"profile\": {\"phone\": \"+1 555 0100\"}}. Field names are as freeapply_get_settings returns them."
    • Changedfreeapply_workflow2 fields changed
      • addedInput schema / properties / name / description
        Added value: +"Procedure to get. Optional; omit to list the procedures."
      • addedInput schema / properties / name / enum
        Added value: +[
        +  "freeapply-setup",
        +  "freeapply-apply",
        +  "freeapply-replies"
        +]
  3. 25 tool updatesv0.1.0
    • First observedfreeapply_add_job
    • First observedfreeapply_autorun
    • First observedfreeapply_check_duplicate
    • First observedfreeapply_check_text
    • First observedfreeapply_fetch_posting
    • First observedfreeapply_finish_reply_check
    • First observedfreeapply_get_answers
    • First observedfreeapply_get_settings
    • First observedfreeapply_get_stats
    • First observedfreeapply_list_jobs
    • First observedfreeapply_open_dashboard
    • First observedfreeapply_preview_shared_data
    • First observedfreeapply_record_reply
    • First observedfreeapply_reply_check_plan
    • First observedfreeapply_save_resume_profile
    • First observedfreeapply_save_resume_text
    • First observedfreeapply_set_outcome
    • First observedfreeapply_site_account
    • First observedfreeapply_site_status
    • First observedfreeapply_status
    • First observedfreeapply_sync_shared_data
    • First observedfreeapply_throttle
    • First observedfreeapply_update_job
    • First observedfreeapply_update_settings
    • First observedfreeapply_workflow

TDQS

A4.1/5.0

Scored across 22 tools

Disambiguation4/5

The tools cover distinct stages of the application lifecycle, and descriptions explicitly cross-reference neighboring tools to reduce confusion. A few clusters remain close (status/settings/stats/list_jobs, site_account/site_status, record_reply/set_outcome), but the guidance mostly distinguishes them.

Naming Consistency4/5

All tools share the consistent freeapply_ prefix and snake_case style, making them predictable to scan. Most names are verb_noun, with minor deviations such as freeapply_status, freeapply_answers, and freeapply_throttle.

Tool Count3/5

At 22 tools, the surface is heavy for a single server and requires the agent to manage many granular operations. Most tools appear justified by the workflow, but the count is in the borderline-heavy range rather than comfortably scoped.

Completeness4/5

The set covers setup, settings, résumé storage, job tracking, duplicate checks, throttling, replies, outcomes, stats, autorun, and sharing, which is broad for the domain. Minor gaps exist, such as no explicit job-deletion tool or standalone job-discovery/search operation.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables users to search for jobs, prefill applications using AI, and automate submissions across major platforms like Lever and Ashby directly from Claude or Cursor. It provides a full suite of tools for managing job queues, profile data, and resumes within a chat interface.
    37
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables Claude to parse CVs, search job boards (Remotive, Arbeitnow, Adzuna, Greenhouse/Lever), tailor resumes and cover letters, and prepare application packages with direct apply links—without ever auto-submitting. It runs 100% locally and free, storing jobs and applications as JSON files.
    -
  • F
    license
    A
    quality
    C
    maintenance
    Enables an LLM client to read a structured CV resource and send tailored application emails to recruiters via SMTP.
    1
    -
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables automated job searching from multiple boards, filtering matches against saved criteria, deduplicating seen postings, and tracking application statuses. Runs locally and integrates with Claude Desktop for natural-language queries and updates.
    -