FreeApply
OfficialFreeApply is a local MCP server that automates AI-assisted job search and application tracking with a private dashboard.
Check FreeApply status, get signed task procedures, and open the local dashboard.
Read and update user settings, résumé text/profile, and AI model choices.
Fetch job postings, claim or skip jobs with duplicate, job-site, and pay-floor checks.
Manage reusable form answers and truthfulness-check cover letters or written answers; save passing cover letters as PDFs.
Update application statuses, list tracked jobs, get job-search statistics, and report job-site sign-out or limit problems.
Get clearance before submitting applications, with pacing and daily-cap enforcement.
Start or finish unattended/scheduled runs with run limits.
Run Gmail reply checks, record employer outcomes, and star/label emails when configured.
Find whether the user has an employer-site account.
Preview or sync shared data according to the user's privacy choices.
It does not type passwords, create accounts, or solve CAPTCHAs; those are flagged for the user.
Uses the Gmail connector to watch for employer replies to job applications, checking every 4 hours by default and optionally starring and/or labeling incoming replies.
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.5 (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 the Gmail app password you connect in setup, new employer emails show up in the dashboard within about 15 minutes, and your AI app sorts them every 4 hours by default (the Gmail connector works too).
Keeps going on its own once setup is done, while your AI app is open; Start and Stop are at the top of the dashboard, with what it's working on right now.
Related MCP server: cv-job-assistant
Install
App | How |
Claude Desktop | Download |
Claude Code, Cursor, VS Code, Windsurf | Windows: |
Claude Code, from this repository |
|
Any other MCP app | Unpack |
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
Restart your AI app and say "Set up FreeApply". The dashboard opens.
Read and accept the Terms of Service and Privacy Policy there yourself (18+). Until you do, every agent tool except
freeapply_statusandfreeapply_open_dashboardrefuses to run, and the agent can never accept for you.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.
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 make: 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.
Stuck: what the site asked for in plain words (a "prove you're a person" check, a code, a warning, a document FreeApply doesn't have, a question only you can answer), with "I applied myself", "Try again later" and "Skip this job".
Configuration
What | Where |
Data folder |
|
Use an existing database in place |
|
Dashboard port |
|
Dashboard only |
|
Flags |
|
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 (frames an email reply check; with an app password saved in Settings it reads, stars and labels the replies itself),
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, LinuxThe 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 |
| The app: an MCP server in Node.js with no dependencies, the dashboard ( |
| Claude Code skills that point to the signed procedures |
| Claude Code plugin and marketplace files |
| What changed in each version |
| 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 toolsfreeapply_check_repliesRun a reply check: plan, read, mark, finishAIdempotent
Runs one email reply check (the freeapply-replies procedure), always beginning with action start, and, when the user saved an email login in Settings, reads and marks their mailbox itself. Each email found is recorded with freeapply_record_outcome. Use: start first; then read (start's mail.reader freeapply) or the Gmail connector (connector); mark after recording each email read returned; finish once everything found is recorded. Behavior: start: read-only, repeatable. read: signs in with the app password kept on this computer (you never see it), returns matching emails, changes nothing. mark: stars and/or labels one email as the user chose in Settings. finish: sets the last check to now, so the next check reads only newer email: only after recording everything found. Returns: start (the plan) {since, gmail (the user's mail settings: action none|star|label|star_and_label, label_name, ...), mail {reader: freeapply|connector, address}, applied [{job_id, company, title, submitted_at}], known_message_ids (already recorded)}. read {emails: [{gmail_message_id, gmail_thread_id, sender, subject, received_at, text}] newest first, already-recorded left out, count}. mark {mail_action} (for freeapply_record_outcome). finish {last_check}. Errors: an action other than start, read, mark or finish; read or mark without a saved email login; the mail server refusing the login.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Required for mark: the outcome you recorded for the email. | |
| action | Yes | start (always first): the plan; read: the mailbox; mark: star or label one email; finish (always last): the check is done. | |
| gmail_message_id | No | Required for mark: the email's id, from read. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well past the annotations by disclosing per-action behavior: start is read-only and repeatable, read authenticates with a locally stored app password the agent never sees and changes nothing, mark mutates stars/labels per the user's Settings choice, and finish advances the last-check watermark, which changes future read results. It also lists failure modes (unknown action, missing saved login, server login refusal). With destructiveHint=false but real state mutation, this is exactly the context an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with a one-line purpose, then cleanly sectioned into Use/Behavior/Returns/Errors, so an agent can scan to the part it needs. It is dense and parenthetical-heavy, and the Returns block is long, though that length is largely licensed by the absence of an output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-mode state machine with no output schema, the definition covers sequencing, authentication requirements, mutation semantics, and the full return shape of each action (plan, email list with field names and ordering, mail_action, last_check). Errors are enumerated, so nothing material is missing before a call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so baseline is 3; the description adds value by tying parameters to the state machine (mark depends on an email id returned by read, and the mark supplants the freeapply_record_outcome kind), which the schema alone does not connect. It stops short of restating per-parameter requirements, so it is incremental rather than exhaustive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb and resource ("Runs one email reply check") and explicitly names the coupled sibling freeapply_record_outcome for recording each found email, so the boundary is clear without opening any schema. It also names the two mailbox paths (freeapply reader vs Gmail connector), which distinguishes it from the account/settings tools in the sibling list.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The "Use:" line gives an explicit ordered protocol — start first, then read via freeapply reader or the Gmail connector, mark after each read email is recorded, finish once everything found is recorded. Exclusions are stated too (finish "only after recording everything found"), leaving nothing 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 letterAIdempotent
Checks a cover letter or free-text answer against what the user really has; saves a passing cover letter as a PDF to upload. Every piece of prose is checked here before you type or attach it (freeapply_update_job only records). Use: before typing any written answer or attaching any letter, and after each fix. Not for short fields straight from settings (name, date, yes/no). Behavior: flags every skill, tool, number or claim the résumé, settings, highlights and saved answers don't support. Without save, 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; refused once the job is applied. Until setup has stored the résumé's text, most claims are reported unsupported. Returns: {ok, problems} (plain sentences: fix, remove or ask the user). With job_id also keywords {used, unused}: the posting's supported skills this text uses / could still use. With save also file {path, name, bytes}, or note (why not saved). Errors: save without kind cover_letter and job_id; unknown job_id.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | cover_letter: also checks the user's length, sign-off, leftover placeholders and that the company is named. answer (default): facts only. | |
| save | No | Save a passing cover letter as a PDF (default false). For a letter, pass it from the first call: checked and saved at once. | |
| text | Yes | The letter or answer, exactly as you will type or attach it. | |
| job_id | No | Adds the posting's keywords; numbers from the job's posting, title, pay, location and posting id, and the user's answers for this job, count as facts. Needed for save. | |
| company | No | The employer, when there is no job_id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond annotations: explains that without save nothing changes, a passing letter becomes a PDF kept with the job, a failing letter is never saved, saving again replaces the file, saving is refused once the job is applied, and claims are mostly unsupported until setup has stored the résumé text. It also names the specific checks (skills, tools, numbers, claims) and the error conditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well structured with labeled Use, Behavior, Returns and Errors sections. Despite being long, every section front-loads the decision-relevant information and no sentence is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description fully compensates by documenting the return shape ({ok, problems}, keywords, file, note) and the error cases. Combined with the detailed usage and behavior sections, an agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description still adds useful cross-parameter constraints: save requires kind cover_letter and job_id, company is the fallback when job_id is absent, and job_id activates keyword analysis and treats posting facts as supported.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: checks a cover letter or free-text answer against the user's real facts and optionally saves a passing cover letter as a PDF. It explicitly distinguishes itself from freeapply_update_job ('only records') and from short settings-derived fields, so an agent can route correctly without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit timing ('before typing any written answer or attaching any letter, and after each fix') and explicit exclusions ('Not for short fields straight from settings (name, date, yes/no)'), plus names the sibling that only records. No inference required.
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: duplicate check, the user's rules, starts tracking, returns the job_id every later call needs. Makes the job's first record (listing: freeapply_list_jobs; changing: freeapply_update_job). Use: before opening any application form; also to record a reviewed job you won't pursue (status skipped + status_note) so it isn't reviewed again. Not for a job already claimed. Behavior, first match wins: posting id already tracked: returns that job (existing true, nothing added); job site the user didn't choose, or signed out or paused: refused (refused says why, sites lists ready ones); same company and title as an applied job: refused as a repost; posted pay below the user's minimum: saved as skipped (rule pay_floor). Otherwise the job is added. A refused or existing claim changes nothing, so repeating the call is safe. Returns: {job_id, existing, status, rule, earlier}. earlier: up to 20 other jobs at the company [{id, title, company, status, same_title}]; if an applied one is clearly the same role under another title, mark this one skipped (freeapply_update_job). restart true (auto-run): the user saved new settings and wants them used now: don't work this job; the run finishes and starts again. Errors: a missing title or company.
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Posting URL; tells the job site. The URL just read by freeapply_fetch_posting keeps its keywords. | |
| title | Yes | As posted. | |
| source | No | Where found: job site id (linkedin, indeed, company_sites, ...) or referral; tells the job site like url. | |
| status | No | found (default): to work on; skipped: a job you won't pursue. | |
| company | Yes | The employer as posted; not a staffing firm, when you can tell. | |
| pay_max | No | Highest posted pay, a number. Feeds the pay floor. | |
| pay_min | No | Lowest posted pay, a number: annual, or hourly if posted hourly. Feeds the pay floor. | |
| location | No | As posted. | |
| pay_text | No | Pay exactly as posted, e.g. "$90k-$110k". | |
| apply_url | No | Application form URL, if different. | |
| fit_notes | No | Why it fits or doesn't, one sentence. | |
| fit_score | No | 0-100, scored as the apply procedure says. | |
| work_mode | No | remote, hybrid or onsite, as posted. | |
| description | No | Short description or key requirements. | |
| external_id | No | The posting's id on its source site; pass it whenever shown: finds the posting again and catches reposts. | |
| status_note | No | For skipped: why, one plain sentence. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover the generic mutation/safety profile, but the description supplies the full decision cascade (already tracked, disallowed/signed-out/paused site, repost match, pay-floor skip), the return shape {job_id, existing, status, rule, earlier} with the meaning of 'earlier' and 'restart', and the missing title/company error. It also discloses the idempotence-like safe-repeat property, which is a mild tension with idempotentHint=false but reads as clarifying the actual state behavior rather than contradicting it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and usage, then a clearly labeled 'Behavior, first match wins' block that prioritizes rules over prose. The telegraphic colon-chained style packs value but is dense enough that an agent must parse carefully to find the branch it needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 16-parameter mutation tool with no output schema, the description covers the refusal conditions, the effective return contract including the 'earlier' list and 'restart' flag, and error behavior. Nothing an agent needs in order to call it correctly and interpret the result appears to be missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: it explains how status=skipped plus status_note are used together for reviewed-but-unpursued jobs, and how posted pay feeds the pay_floor rule outcome. It stops short of walking through the remaining optional posting fields, which the schema already documents well.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource up front ('Claims a job before you work on it') plus the immediate side effects (duplicate check, rules, tracking) and the returned job_id. It also names what it is not by pointing to freeapply_list_jobs for listing and freeapply_update_job for changing, so it is distinguishable from every sibling 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use ('before opening any application form'), a secondary use case (recording a reviewed job not pursued via status skipped + status_note), and an explicit exclusion ('Not for a job already claimed'). Alternative tools are named for the adjacent operations, leaving nothing to inference.
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
Go-ahead for one submit after checking the pace, the user's limits and, in auto-run, the Stop button. Comes right before the submit; freeapply_update_job refuses applied without its clearance. Use: right before every submit, with job_id. Not early, not for a job you won't submit now: each clearance counts toward the per-minute pace at once. Behavior: at most 3 submits a minute (or the user's slower setting) and the user's daily cap. A clearance: one job, 15 minutes, used up when applied is recorded; asking again for the same job issues a new one; kept only while FreeApply runs. Parameters: job_id ties the clearance to that one job (without it you only see the pace). method: external (employer or ATS form, the default), easy_apply or email; the pace and daily cap count submits by that method, and easy_apply also needs one-click apply allowed in Settings. run_id, only in auto-run (from freeapply_manage_autorun start), adds the user's Stop and limits, and counts as the run checking in. 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, 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: freeapply_manage_autorun action finish. restart true: the user saved new settings and wants them used now: submit and record this job, start no other, finish the run; the next begins at once.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | No | The job about to be submitted. | |
| method | No | How you will submit (default external). | |
| run_id | No | Auto-run only: the run_id from freeapply_manage_autorun start. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With annotations already declaring non-read-only, non-idempotent, and non-destructive behavior, the description adds substantial stateful context: rate limits, daily caps, 15-minute clearance expiry, one-job scope, method-specific counting, and auto-run Stop/restart semantics. These details go well beyond what the annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense and well-structured with Use, Behavior, Parameters, and Returns sections, and the core purpose is front-loaded. It is somewhat long and repeats the 'right before submit' timing in the opening and Use section, but the length is largely justified by the tool's stateful complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex, non-idempotent stateful tool with no output schema, the description is complete enough: it explains preconditions, rate limits, parameter effects, return fields, and how to react to clear=false, refused, stop_run, and restart outcomes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description still adds meaningful semantics: job_id ties clearance to one job and without it only pace is visible; method affects pace/daily cap and easy_apply requires one-click apply enabled; run_id only applies in auto-run and activates Stop/limits and run check-in behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action and resource: a go-ahead/clearance for one submit, checked against pace, user limits, and auto-run Stop state. It also distinguishes itself from freeapply_update_job by noting that job update refuses 'applied' 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit timing and exclusions: use right before every submit, with job_id, not early, and not for a job that will not be submitted now. It also routes stop_run handling to freeapply_manage_autorun action finish.
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 postingARead-onlyIdempotent
Fetches one job posting from the user's computer, trimmed: description, form questions, suggested answers, skills asked. Costs few tokens next to the browser, which you still use to fill and submit the form. Use: read each posting you found before scoring or applying. FreeApply has no job search of its own: search the user's job sites in the browser. Not for search-result or sign-in pages: read those in the browser. Behavior: read-only; one web request. Greenhouse, Lever, Ashby via their public APIs, other sites as page text. Public http(s) only: an address on this computer or a local network, or a redirect to one, is refused. Remembered this session, so freeapply_claim_job keeps its keywords. Parameters: url, the posting or its application form; max_chars caps only the description (default 6000, at least 500; description_chars tells you when it was cut); source, the job site where you found it (e.g. linkedin), picks the saved answers meant for that site. Returns: ats, title, company, location, work_mode, pay, description, description_chars (full length), questions [{label, required, type, options}], suggested_answers (from settings and saved answers; answer anything else only from the résumé or the user), keywords {matched, missing, coverage}: use matched in the posting's words, never claim missing; coverage = matched share in %, null if the posting names none. Errors: a bad or local address, or an unfetchable page, with the reason: read it in the browser. Next: freeapply_claim_job.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | The job page or its application form. | |
| source | No | Job site id where found, e.g. linkedin. | |
| max_chars | No | Description cap in characters (default 6000). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover read-only/idempotent/open-world, but the description adds substantive behavior: one web request, which sites use public APIs vs. page text, refusal of localhost/private-network addresses and redirects to them, and session-level caching so freeapply_claim_job retains keywords. It also specifies error behavior and recovery ("read it in the browser").
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Labeled sections (Use / Behavior / Parameters / Returns / Errors / Next) make it scannable and the critical routing guidance is front-loaded. It is long, and the token-cost aside ("Costs few tokens next to the browser...") is the least essential sentence, though it does reinforce the browser-vs-tool split.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no annotations covering returns, the description fully carries that burden: it enumerates every returned field including items, suggested_answers provenance, and the keywords/coverage semantics with usage rules ("use matched in the posting's words, never claim missing"). Errors and the natural next tool are also documented.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% so the baseline is 3; the description goes beyond it by explaining that max_chars caps only the description and that description_chars signals truncation, and by explaining what `source` functionally does (selects saved answers for that site). The url semantics are merely restated ("the posting or its application form"), which is already in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("Fetches one job posting") plus exactly what is returned (description, form questions, suggested answers, skills asked). It also disambiguates from siblings by naming freeapply_claim_job as the next step and clarifying that search happens in the browser, not here.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use ("read each posting you found before scoring or applying") and explicit when-not ("Not for search-result or sign-in pages: read those in the browser"), plus the key constraint that FreeApply has no job search of its own. It routes to the correct alternative for the excluded cases.
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 accountARead-onlyIdempotent
Whether the user already made an account on an employer's careers site, and with which email. Employer sites only (job boards such as LinkedIn that signed the user out: freeapply_report_site_problem). Use: when an application form asks you to sign in or create an account. Not for signing in or up: FreeApply stores no 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, the host the sign-in form is on, or any URL there. It is reduced to the domain without www. and matched exactly, so careers.example.com and example.com are different sites: pass the one the form is on. Returns: known account {domain, email_used, created_at, job_id, note}: ask the user to sign in in the browser, then continue in their session. None {domain, account: null}: freeapply_update_job status needs_account, account_url = the sign-up page. Errors: a site that isn't a domain or web address.
| Name | Required | Description | Default |
|---|---|---|---|
| site | Yes | Domain or any URL on it, e.g. careers.example.com. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent, so the bar is lower, but the description still adds substantial context beyond them: the data source (accounts the user records on the dashboard's Needs you tab), the authentication boundary (no passwords stored), and the two branch outcomes with concrete field names.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Labeled sections (Use / Behavior / Parameters / Returns / Errors) make it scannable and the purpose is front-loaded. It is dense and slightly long, but nearly every clause carries actionable information; only the returns-section next-step guidance could be trimmed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description supplies the return shapes for both branches (account object fields vs. {domain, account: null}), the follow-up action for each, and the error condition. Nothing an agent needs to invoke or interpret this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (baseline 3), but the description adds genuinely new meaning: the input is normalized to the domain with 'www.' stripped and matched exactly, so careers.example.com and example.com are distinct — and it tells the agent which one to pass. That is exactly the failure mode an agent would otherwise hit.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
First sentence states a specific question the tool answers: whether the user already has an employer careers-site account and with which email. It scopes the resource explicitly ('Employer sites only') and names the excluded class (job boards like LinkedIn) plus the sibling that handles them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger ('when an application form asks you to sign in or create an account') and an explicit exclusion ('Not for signing in or up: FreeApply stores no passwords and you never type one'). It also names freeapply_report_site_problem for job boards and freeapply_update_job for the not-found branch, so alternatives are fully routed.
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 settingsARead-onlyIdempotent
Reads the user's settings: who they are, what they seek and how FreeApply should work. Single form answers: freeapply_manage_answers; whether FreeApply can run: freeapply_get_status. Use: once per session or helper, and again after each auto-run go, before scoring jobs or filling a form. With the résumé text and the user's own words, the only source of facts about the user: never invent beyond it. To change: freeapply_update_settings. Behavior: read-only; never includes installation secrets. Parameters: sections, the sections to return (default all, named under Returns): ask only for what the step needs, e.g. ["profile", "eligibility"] for a form, and leave out resume, the largest, unless you need its text. Returns: {settings, missing}. Sections: profile, targets, eligibility, resume (file paths, text, profile; the user adds and replaces résumé files in the dashboard), cover_letter, automation, autorun, gmail, custom_answers, models, model_choices, sharing (choices only). missing: required fields still empty [{key, label}]; while non-empty, apply nowhere: open the settings tab (freeapply_open_dashboard) and ask the user to fill them. Errors: an unknown section; the message lists valid ones.
| Name | Required | Description | Default |
|---|---|---|---|
| sections | No | Section names to return (default all). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations' read-only/idempotent hints, it discloses security context ('never includes installation secrets'), an epistemic constraint ('the only source of facts about the user: never invent beyond it'), and critical gating behavior: while `missing` is non-empty, 'apply nowhere' and the agent should open the settings tab. It also describes error behavior for unknown sections.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded and broken into labeled segments (Use, Behavior, Parameters, Returns, Errors), with no wasted sections. It is dense but mostly earns its length; the sentence 'With the résumé text and the user's own words, the only source of facts about the user: never invent beyond it' is slightly awkward and could be clearer.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read tool with rich annotations but no output schema, the description covers everything an agent needs: return shape ({settings, missing}), the full section list, missing-field gating, and error handling. Nothing material is missing to call or interpret it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents the `sections` parameter at 100% coverage, so the baseline is 3. The description significantly adds meaning by enumerating valid section names under Returns, advising to request only what the step needs with a concrete example, and warning that `resume` is the largest and should be omitted unless its text is required.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Reads the user's settings: who they are, what they seek and how FreeApply should work.' It explicitly distinguishes itself from freeapply_manage_answers, freeapply_get_status, and freeapply_update_settings, so an agent can route correctly without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit timing: 'once per session or helper, and again after each auto-run go, before scoring jobs or filling a form.' It also names the alternatives for single-form answers and status checks, and directs changes to freeapply_update_settings. When and when-not are both covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
freeapply_get_statsGet job-search statisticsARead-onlyIdempotent
The user's job search in numbers: applications, replies, interviews, offers, rates (individual jobs: freeapply_list_jobs; whether FreeApply can run: freeapply_get_status). Use: to report progress, e.g. when wrapping up a session. Not for finding a particular job. Behavior: read-only, cheap: counted fresh from the local database each call, nothing cached. No parameters. Returns: tracked, applied, applied_today, queued, needs_you (jobs waiting on the user), interviews, offers, rejections, acknowledged, response_rate (% 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, by_method, daily (applications per day), top_companies, top_titles, top_jobs.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, yet the description still adds value beyond them: 'counted fresh from the local database each call, nothing cached' discloses cost and data freshness, which annotations cannot express. It also defines a non-obvious metric inline ('response_rate – % of applications with a real reply; automatic acknowledgements not counted') and clarifies 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with a one-line purpose, then labeled Use/Behavior/Returns blocks. The Returns enumeration is long but each field grouping (counts, rates, aggregations) earns its place because no output schema exists. Slightly dense, but structured rather than rambling.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must convey what comes back, and it does so field-by-field including units (percent) and semantics (needs_you = jobs waiting on the user; daily = applications per day). Combined with cost/freshness disclosure, an agent has everything needed to call and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so the schema carries nothing to explain; the description correctly states 'No parameters', removing any question about required filters. It stops there rather than adding semantics a parameterless tool would need, which is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a concrete verb+resource framing ('The user's job search in numbers: applications, replies, interviews, offers, rates') and immediately names the two siblings it is not (freeapply_list_jobs, freeapply_get_status). An agent can distinguish this from list_jobs and get_status without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage section: 'Use: to report progress, e.g. when wrapping up a session. Not for finding a particular job.' Both a positive trigger and an exclusion are stated, and the alternative for per-job lookups is named. 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_get_statusCheck FreeApply and get a procedureARead-onlyIdempotent
Whether FreeApply can work now, plus the signed step-by-step procedure for a task. About FreeApply itself (user details: freeapply_get_settings; job search: freeapply_get_stats). Use: first in every session and before each task; with wait after asking the user to accept the Terms or finish setup in the dashboard. Works while locked or the Terms are unaccepted, so it can say why. Behavior: read-only: reports what FreeApply set up when it started (data folder, database, dashboard, the résumé copy to upload). wait holds the call up to 10 minutes until the Terms are accepted and setup is complete, and returns within seconds of that. Parameters: none for status only; procedure adds that task's signed steps; lane (with procedure freeapply-apply) is for a helper: only the hard rules and that lane's steps, with a short status; wait as above, with or without procedure. Returns: workflow {ok, problem}, terms {ok}, setup_complete, missing, sites [{id, name, ready}] (chosen job sites), autorun, update, dashboard (URL), data_dir, documents {dir, resume, cover_letters}, stats, procedures, models {can_delegate, rescan, levels, lanes, unfilled} (each level and lane {model, effort, source}; model current = your own model does it). With procedure also procedure {name, description, text, workflow_version, workflow_hash}, null while locked. wait_again true: a wait ran out first; call again. Next: workflow.ok false: tell the user why, stop. terms.ok or setup_complete false: follow freeapply-setup. models.rescan true: do its AI models step first.
| Name | Required | Description | Default |
|---|---|---|---|
| lane | No | A helper's lane of freeapply-apply; the agent that starts helpers omits it. | |
| wait | No | Hold the call until the Terms are accepted and setup is complete (up to 10 minutes). | |
| procedure | No | freeapply-setup (first run; Terms or settings missing; starting auto-run), freeapply-apply (find jobs, apply) or freeapply-replies (email reply check). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/destructive=false, but the description adds substantial non-obvious behavior: wait can hold up to 10 minutes until Terms are accepted, returns within seconds of completion, and it discloses what setup state is reported. It also explains wait_again semantics for a timed-out wait.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Structure is excellent — purpose, use, behavior, parameters, returns, and next steps are clearly separated and front-loaded. It is dense and the Returns enumeration is long, but almost every clause carries actionable information for a complex tool; minor verbosity only.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description must explain returns — and it does thoroughly, enumerating the workflow, terms, setup, sites, documents, and procedure fields. It also provides failure-branch guidance (workflow.ok false → stop; terms/setup false → freeapply-setup; rescan → models step), making it complete for a tool of this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description materially adds meaning: 'lane (with procedure freeapply-apply) is for a helper: only the hard rules and that lane's steps,' which explains an interaction constraint the schema does not. It doesn't fully enumerate each param's individual effect, but the added interaction semantics push it above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening line states a specific dual purpose: reporting whether FreeApply can work now and returning a signed step-by-step procedure. It also explicitly disambiguates from siblings by naming freeapply_get_settings (user details) and freeapply_get_stats (job search), so an agent can route without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is prescriptive: 'first in every session and before each task,' and use the wait flag after asking the user to accept Terms or finish setup. It even notes it works while locked/unaccepted, so its purpose as a diagnostic tool is unambiguous.
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 jobsARead-onlyIdempotent
Lists the user's tracked jobs, most recent activity first (submitted, else updated, else found): the jobs themselves (totals and rates: freeapply_get_stats). Use: to find a job_id, look up one job by job_id, or answer questions about particular jobs. Not for adding or changing jobs (freeapply_claim_job, freeapply_update_job). Removing a job is the user's, in the dashboard. Behavior: read-only. Filters combine: a job must match all given. limit and offset page through the same order (default 200 from 0); a page shorter than limit is the last. Parameters: job_id returns just that job (empty if unknown); status and outcome match exactly; search finds text in the title, company or location, ignoring case. Returns: [{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, reply_count}]; empty when nothing matched.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Most jobs to return (default 200). | |
| job_id | No | One job by its id. | |
| offset | No | Jobs to skip (default 0). | |
| search | No | Text to find. | |
| status | No | Exact status filter. | |
| outcome | No | Exact employer-outcome filter. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint/idempotentHint/destructiveHint, so the 'read-only' line is redundant, but the description goes well beyond them: filter combination is AND across all given params, pagination preserves the same ordering with a short-page-means-last rule, and empty results are specified for both no-match and unknown job_id. That is the kind of behavioral detail annotations cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then clearly segmented into Use / Behavior / Parameters / Returns, with zero filler. The enumerated 21-field return list is long, but it substitutes for a missing output schema, so it earns its space; only the restated defaults are pure repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the field-level return list is exactly what an agent needs to know what it will get back, and ordering, filtering, pagination limits, and empty-result behavior are all covered. Nothing an agent needs to invoke this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline would be 3; the description earns above that by adding semantics the schema lacks — 'search' is scoped to title, company or location and is case-insensitive, job_id returns empty (not an error) when unknown, and status/outcome are exact matches. The default-200/offset-0 behavior is restated rather than added, keeping it off a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Lists the user's tracked jobs') plus the exact ordering rule (submitted, else updated, else found). It explicitly separates itself from freeapply_get_stats (totals/rates) and freeapply_claim_job / freeapply_update_job (mutation), so an agent can route correctly without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
A dedicated 'Use:' clause enumerates the three concrete jobs this serves (find a job_id, look up one job, answer questions about particular jobs), and a 'Not for' clause names the sibling tools that handle adding/changing plus notes that removal happens in the dashboard. Both the positive and negative routing conditions are explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
freeapply_manage_answersGet or save the user's answersADestructiveIdempotent
Gets or saves the user's own answers to specific form questions, so you never guess one (general details: freeapply_get_settings). A new question for the user goes through freeapply_update_job status needs_info instead. Use: get before retrying a job the user re-queued from the Needs you tab; save when the user answers a question in this conversation, for later forms. Save only the user's own words: saved answers count as facts in freeapply_check_text. Behavior: get is read-only. save replaces the answer saved under the same question; an empty answer removes it. Returns: get {job_id, answers: [{label, answer}] the user gave for this job, saved_answers: {question: reusable answer}, cover_letter: the job's saved letter {path, text} (text: for a text-box letter field) or null}. save {label, saved, removed, saved_answers}. Errors: get without job_id or with an unknown one; save without label; an action other than get or save.
| Name | Required | Description | Default |
|---|---|---|---|
| label | No | Required for save: the question as forms word it, e.g. "Are you willing to relocate?". | |
| action | Yes | get (read-only): a job's answers and saved letter; save (writes): one reusable answer the user just gave. | |
| answer | No | For save: the user's own words; empty removes the saved answer. | |
| job_id | No | Required for get. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: it discloses that save replaces the answer under the same question and that an empty answer removes it, which explains the destructiveHint=true and idempotentHint=true flags in concrete terms. It also warns that saved answers count as facts in freeapply_check_text, a downstream effect an agent could not infer, and lists error conditions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the core verb+resource, then organizes the rest into labeled Use/Behavior/Returns/Errors segments, which is easy to scan. Slightly dense with parenthetical cross-references, but every sentence carries actionable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by spelling out both return shapes (job_id, answers, saved_answers, cover_letter for get; label, saved, removed, saved_answers for save) and the error cases. Nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so label, action, answer, and job_id are already fully documented with the same wording ('the user's own words', 'empty removes the saved answer'). The description adds error conditions tied to parameters (get without job_id, save without label) but little semantic detail beyond the schema, so baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb pair and resource: gets or saves the user's own answers to specific form questions. It immediately distinguishes itself from freeapply_get_settings (referenced as 'general details') and from freeapply_update_job with status needs_info for brand-new questions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'Use:' sentence gives explicit triggering conditions for each action — get before retrying a re-queued job, save when the user answers in-conversation. It also names the alternative path for a new question (freeapply_update_job status needs_info), so when-not-to-use is covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
freeapply_manage_autorunStart or finish an auto-runA
Keeps FreeApply applying on its own from this session, with no scheduled task: start waits until something is due, finish ends a run (freeapply_get_status only shows the run state). Use: auto-run mode of freeapply-apply, which setup's last step enters: start with wait (takeover on the first call), finish after each run, then start again. Not in a session the user runs by hand. Behavior: start with wait holds the call up to 10 minutes while nothing is due (auto-run stopped by the user's Stop or a limit in Settings, the rest after a search found nothing new, the daily cap) and returns as soon as something is, within seconds of the user pressing Start. One session runs it at a time. A run checks in with each job-work tool call and freeapply_clear_to_submit (15 minutes without one counts as ended); freeapply_clear_to_submit with the run_id ends it at a hard stop. finish releases the run and starts the rest (autorun.every_hours), or none when the user asked for a restart with new settings; harmless on a run that already ended. Parameters: action start or finish. wait (start): hold as above; without it start answers at once. takeover (start with wait): only on the call right after the user asked for setup or to keep applying: it presses Start (clears a Stop, a reached limit and the rest) and makes this session the runner; the session it replaced gets replaced at its next start. run_id (finish): the run start returned. summary (finish): one line shown in the dashboard's run history. Returns: start {go: true, run_id, minutes (left before the time limit, null: none), max_applications, sites}; {go: false, replies_due: true}: do freeapply-replies, then start again; {go: false, needs_user: terms|setup}: ask the user (freeapply_open_dashboard), freeapply_get_status with wait, then start again; {go: false, wait_again: true}: start again; {go: false, replaced: true} or any other go false: end quietly. finish {finished, applied_this_run}, null for a run no longer active. Errors: finish without run_id; an action other than start or finish.
| Name | Required | Description | Default |
|---|---|---|---|
| wait | No | For start in auto-run mode: hold until something is due. | |
| action | Yes | start a run (with wait: when one is due); finish it. | |
| run_id | No | Required for finish. | |
| summary | No | For finish: e.g. "applied 4, needs you 2" (up to 500 characters). | |
| takeover | No | For start with wait: the call right after the user asked to start. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond annotations by describing the 10-minute wait behavior, takeover semantics, single-runner constraint, check-in requirements, hard-stop behavior via freeapply_clear_to_submit, and finish scheduling. These are critical stateful behaviors for an agent orchestrating the auto-run loop.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long and dense, but it is structured into purpose, usage, behavior, parameters, returns, and errors. Most sentences carry necessary state-machine semantics, though some parentheticals could be tightened without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the full control flow for a complex stateful tool: expected returns for go true/false branches, needs_user handling, replaced/wait_again cases, finish return values, and error conditions. With no output schema, this description provides the return semantics an agent needs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds operational meaning: wait holds until something is due, without wait start answers immediately, takeover applies only to the call right after the user asked, run_id is from start, and summary appears in dashboard history. This materially supplements the terse schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific workflow verb/resource: keeping FreeApply applying automatically via start/finish actions. It explicitly distinguishes itself from freeapply_get_status and from manual user-run sessions, so an agent can identify its role without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage sequencing: start with wait, finish after each run, then start again, as part of setup's auto-run mode. It also says when not to use it (a session the user runs by hand) and names freeapply_get_status as the state-only alternative.
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 browserARead-onlyIdempotent
Opens the local FreeApply dashboard in the user's browser, one tab (freeapply_get_status only reports its URL). Use: when the user must act there: accept the Terms, fill settings, answer questions waiting on them, review applications and replies. Not for reading data: other tools return it. Behavior: changes no data. Starts the dashboard if needed at http://127.0.0.1:7878 or the next free port; reachable only from this computer. Parameters: tab, the page to open: overview (default; shows the Terms until they're accepted), settings (setup fields), issues (Needs you: questions, sign-ups), applications or replies. Returns: {url, opened}. url null: it couldn't start (no free port); tell the user. opened false with a url: no browser launched; give the user the url.
| Name | Required | Description | Default |
|---|---|---|---|
| tab | No | The page to open (default overview). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive/non-open-world, but the description adds real context beyond them: no data is changed, the dashboard is started on demand with a port fallback (127.0.0.1:7878 or next free port), and it is reachable only from this machine. It also discloses the two failure modes and what the agent should do in each.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action, then organized under Use:/Behavior:/Parameters:/Returns: labels so an agent can scan to the section it needs. Dense rather than padded — no sentence repeats a structured field verbatim, and the Returns guidance is load-bearing because there is no output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Though no output schema exists, the description documents the return shape ({url, opened}) and the meaning of each degenerate case, plus the localhost-only constraint and side effects. Nothing needed to invoke it correctly or interpret the result is missing for a single optional-enum-parameter tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100% with an enum, so the baseline is 3, but the description goes further by explaining what each enum value actually surfaces — overview (default; shows the Terms until accepted), settings, issues ("Needs you"), applications, replies. That is meaning the schema does not carry, and it matters for choosing a tab.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("opens the local FreeApply dashboard in the user's browser") and immediately delimits it against the nearest sibling: freeapply_get_status only reports the URL while this one actually opens a tab. An agent can pick between the two without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use list ("when the user must act there: accept the Terms, fill settings, answer questions waiting on them, review applications and replies") paired with an explicit exclusion ("Not for reading data: other tools return it"). Both the selection condition and the anti-pattern are named.
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 didAIdempotent
Records what an employer did with an application (your side, e.g. applied or skipped: freeapply_update_job). Use: for each employer email found in a reply check, between freeapply_check_replies 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): stores it; 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: sets the outcome exactly, whatever its rank. The email fields fill the dashboard's Replies tab. Returns: with an email {recorded (false: recorded before), kind, job_id, outcome (the job's, afterwards)}, job_id and outcome null without job_id; without one {job_id, outcome}. Errors: an unknown job_id; no job_id and no email; an empty outcome with an email.
| Name | Required | Description | Default |
|---|---|---|---|
| job_id | No | From the reply-check plan or freeapply_list_jobs. Required without an email; with one optional, but without it no outcome changes. | |
| sender | No | Email: sender address. | |
| company | No | Email: the employer that sent it. | |
| outcome | Yes | What 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 (without an email only). | |
| subject | No | Email: subject line. | |
| summary | No | Email: what it says, one sentence of at most 20 words, no personal data beyond what is needed. | |
| mail_action | No | Email: what you did with it in Gmail: starred, labeled:<name>, starred+labeled:<name> or none. | |
| received_at | No | Email: when it arrived (ISO 8601). | |
| gmail_thread_id | No | Email: Gmail thread id. | |
| gmail_message_id | No | The employer email's Gmail message id. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, it explains the rank-based outcome update rule, duplicate-email idempotency, exact-setting behavior without an email, return shapes, and error cases. These details materially help the agent understand side effects and failure modes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well structured with Use, Behavior, Returns, and Errors sections. It front-loads the core purpose and avoids wasting space on restating schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 10 parameters, no output schema, and non-trivial conditional behavior, the description covers usage, side effects, returns, and errors adequately. An agent has enough information to call it correctly in both email and non-email modes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is already 100%, the description adds crucial conditional semantics: with gmail_message_id the outcome is rank-gated, without it the outcome is set exactly, and job_id has different implications in each mode. It also explains what the email fields contribute to the dashboard.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: recording what an employer did with an application. It also explicitly distinguishes this from the user's own application steps, naming freeapply_update_job as the tool for that.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit trigger conditions: for each employer email found during a reply check, and when the user reports a call or corrects an outcome. It also states what the tool is not for and routes that case to 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_report_site_problemReport a job site signed out or limitedADestructiveIdempotent
Marks a job site the user chose in Settings (e.g. LinkedIn, Indeed) unusable for now: it signed the user out or showed its own daily limit (an employer's own careers site: freeapply_find_site_account). Use: as soon as a chosen site shows a sign-in page or a daily limit; then keep applying on the ready sites or company career sites. Never type a password. Behavior: signed_out: unavailable until the user signs in again and confirms it in the dashboard; limit_reached: paused until midnight. Meanwhile freeapply_claim_job refuses new jobs from it. Reporting again changes nothing; only the user can mark a site ready. Returns: {site, status, sites} (each chosen site with ready). Errors: a site the user didn't choose.
| Name | Required | Description | Default |
|---|---|---|---|
| site | Yes | Job site id, as freeapply_get_status lists it in sites. | |
| status | Yes | signed_out: a sign-in page, or the site says you're signed out. limit_reached: the site's own daily limit, e.g. "You reached today's Easy Apply limit". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: it explains the per-status consequences (unavailable until the user signs in and confirms; paused until midnight), the downstream effect on freeapply_claim_job, and that re-reporting is a no-op and only the user can restore readiness. That gives the agent the lifecycle and side effects of a destructiveHint=true mutation, which the annotations alone do not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the action, then labeled Use/Behavior/Returns/Errors sections, with no filler sentences. The telegraphic, colon-heavy style is dense but each line carries information an agent needs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Fills the gap left by the absent output schema by documenting the return shape {site, status, sites} and names the error case (a site the user didn't choose). Combined with the state-transition details, an agent has everything needed to call it correctly and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both parameters are fully described in the schema, including enum meanings and example phrasing for limit_reached. The description adds only illustrative site examples and the note that only user-chosen sites are valid, so baseline 3 is right.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb+resource (marks a chosen job site unusable) with the concrete trigger conditions (signed out or daily limit). It also distinguishes the employer-careers case by routing to freeapply_find_site_account, so an agent can separate this from sibling tools 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger ('as soon as a chosen site shows a sign-in page or a daily limit'), the required follow-up behavior ('keep applying on the ready sites or company career sites'), and a hard exclusion ('Never type a password'). Alternatives are named 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_update_jobUpdate a job's application statusADestructiveIdempotent
Sets a claimed job's status: your side of the application (employer's response: freeapply_record_outcome; adding a job: freeapply_claim_job). Use: after a submit (applied); giving up (skipped, failed); 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. Behavior: replaces the status. Enforced: applied needs a fresh freeapply_clear_to_submit clearance for this job; cover_text must pass the truthfulness check; an applied job 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, refused with the answers to use. A field marked for one status is refused with any other. Returns: {job_id, status} and when relevant: already_waiting; questions (each added, duplicate, grouped or already_answered, with its answer), 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.
| Name | Required | Description | Default |
|---|---|---|---|
| note | No | What happened, for the user: one plain sentence, no technical terms, e.g. "The site asked to prove you're a person." | |
| job_id | Yes | The job's id, as returned by freeapply_claim_job or freeapply_list_jobs. | |
| method | No | applied only: how it was submitted. | |
| status | Yes | 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). | |
| questions | No | needs_info only, at least one: the form's unanswered questions, each with a plain prompt and the simplest kind of answer that fits. | |
| cover_path | No | applied only: the letter file sent, if not the saved one. | |
| cover_text | No | applied only: the letter sent, if not the saved one. | |
| account_url | No | needs_account only: the site's sign-up page. Jobs with the same one share a card; one "I made the account" re-queues them all. Default: the application link, so jobs rarely share. | |
| letter_sent | No | applied only; required when a letter is saved for the job (freeapply_check_text save): true if attached or pasted, false if not (letter dropped from the record). | |
| resume_path | No | applied only: the résumé file sent, if not the documents copy (recorded by default). | |
| confirmation | No | applied only: the confirmation text or number the site showed. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations, the description discloses key behavior: status replacement, fresh clearance enforcement for applied, truthfulness checks on cover_text, the rule that applied jobs only the user can change, needs_info re-queue behavior, and refusal rules for status-specific fields. It also describes return fields and error conditions, giving the agent operational context needed to invoke it safely.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded and organized into clear Use, Behavior, Returns, and Errors sections. Despite its length, every section earns its place by covering a complex multi-status tool with 11 parameters.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, but the description supplies the relevant return shape and error behavior. Combined with annotations and full schema coverage, it gives enough information for an agent to call the tool correctly across statuses and edge cases.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already carries most parameter meaning and baseline is 3. The description adds conditional semantics beyond the schema, such as applied-only enforcement, needs_info question handling, needs_account sign-up page behavior, and refusal when a field is supplied for the wrong status.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource: it sets a claimed job's application status. It immediately distinguishes the tool from siblings by naming freeapply_record_outcome for employer responses and freeapply_claim_job for adding jobs, so an agent can identify the correct 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly maps statuses to situations: applied after submit, skipped/failed when giving up, needs_info/needs_account/blocked when the user must act. It also names alternative tools for adjacent operations, leaving little ambiguity about when to use this tool versus siblings.
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éADestructiveIdempotent
Changes the user's settings: facts and preferences the user states, the résumé's text and profile (setup), and the AI models scan. Reading: freeapply_get_settings; single form answers: freeapply_manage_answers. Use: when the user states a fact or preference, in setup's résumé step, in the AI models step. Never fill a field the user didn't give you. Behavior: overwrites the sent fields, no undo. Deep merge: only sent fields change, nested objects merge, lists are replaced whole. User-only sections (legal, sharing, automation, autorun, onboarding, integrity, model_choices) are skipped and listed in ignored. All or nothing: one wrong field saves nothing. Parameters: patch, nested by section with the names freeapply_get_settings returns, e.g. {"targets": {"min_pay": 60000}}. Writable: profile, targets, eligibility, cover_letter, custom_answers (one at a time: freeapply_manage_answers), gmail (not last_check or manual_logins); resume only text and profile {headline, skills, titles, education, certifications}, taken from the résumé text alone; models only the scan {app, current, can_delegate, available, efforts}, read from your own tools, which replaces the last one. Returns: {changed, ignored, setup_complete, missing}; after a scan also models (model and effort chosen per level). Errors: nothing writable, unknown section or field, wrong type, value outside its choices (e.g. cover_letter.length short|standard|long), résumé files (the user adds them in the dashboard), malformed scan; the message names every problem.
| Name | Required | Description | Default |
|---|---|---|---|
| patch | Yes | Fields to change, nested by section. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark it destructive and idempotent, and the description adds substantial operational context: overwrites without undo, deep-merge semantics, whole-list replacement, skipped user-only sections listed in ignored, and all-or-nothing saves. It also describes error behavior where the message names every problem.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is dense but organized into clear operational clauses: Changes, Use, Behavior, Parameters, Returns, and Errors. The purpose and usage are front-loaded, and each section carries distinct information needed for a complex nested update tool rather than repeating structured fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive nested update tool with no output schema, the description covers return fields (changed, ignored, setup_complete, missing, and models after a scan) and the main error cases. Combined with merge and skipped-section behavior, it is complete enough for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema only says patch is an object nested by section. The description supplies the actual section names, an example patch, the writable fields, résumé and model-scan restrictions, and validation constraints such as cover_letter.length choices, which is far beyond what the schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the specific resource (user settings) and the three content areas it saves: stated facts/preferences, résumé text and profile, and the AI model scan. It also names freeapply_get_settings for reading and freeapply_manage_answers for single form answers, distinguishing it from those siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use it: when the user states a fact or preference, during setup's résumé step, or in the AI models step. It also gives a clear when-not rule: never fill a field the user did not provide, and routes reading to freeapply_get_settings and single answers to freeapply_manage_answers.
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.
20 tool updates
v1.0.6- Removed
freeapply_autorun - Added
freeapply_check_replies - Changed
freeapply_clear_to_submit3 fields changed- changed
Input schema / properties / job_id / descriptionPrevious value: -"The job about to be submitted; without it you only see the pace."New value: +"The job about to be submitted." - changed
Input schema / properties / method / descriptionPrevious value: -"How you will submit: external (employer or ATS form; default), easy_apply (a job board's one-click apply; refused while one-click apply is off) or email."New value: +"How you will submit (default external)." - changed
Input schema / properties / run_id / descriptionPrevious value: -"Unattended run only: the run_id from freeapply_autorun start; first checks that run's limits and the dashboard's Stop button, and keeps the run alive."New value: +"Auto-run only: the run_id from freeapply_manage_autorun start."
- Changed
freeapply_fetch_posting1 field changed- changed
Input schema / properties / source / descriptionPrevious value: -"Job site id where found, e.g. linkedin; picks the saved answers meant for that site."New value: +"Job site id where found, e.g. linkedin."
- Changed
freeapply_find_site_account1 field changed- changed
Input schema / properties / site / descriptionPrevious value: -"Domain or any URL on it, e.g. careers.example.com; reduced to the domain without www. and matched exactly (careers.example.com and example.com differ)."New value: +"Domain or any URL on it, e.g. careers.example.com."
- Changed
freeapply_get_settings1 field changed- changed
Input schema / properties / sections / descriptionPrevious value: -"Sections to return (default all), e.g. [\"profile\", \"eligibility\"] for a form; omit resume, the largest, unless you need its text."New value: +"Section names to return (default all)."
- Added
freeapply_get_stats - Added
freeapply_get_status - Removed
freeapply_job_stats - Changed
freeapply_list_jobs4 fields changed- added
Input schema / properties / job_idAdded value: +{ + "description": "One job by its id.", + "minimum": 1, + "type": "integer" +} - changed
Input schema / properties / limit / descriptionPrevious value: -"Most jobs to return (default 200); fewer returned means the end."New value: +"Most jobs to return (default 200)." - changed
Input schema / properties / offset / descriptionPrevious value: -"Jobs to skip, for the next page (default 0)."New value: +"Jobs to skip (default 0)." - changed
Input schema / properties / search / descriptionPrevious value: -"Text in the title, company or location, ignoring case."New value: +"Text to find."
- Added
freeapply_manage_answers - Added
freeapply_manage_autorun - Changed
freeapply_open_dashboard1 field changed- changed
Input schema / properties / tab / descriptionPrevious value: -"Page: overview (default; shows the Terms until accepted), settings (setup fields), issues (Needs you: questions, sign-ups), applications, replies."New value: +"The page to open (default overview)."
- Removed
freeapply_reply_check - Changed
freeapply_report_site_problem1 field changed- changed
Input schema / properties / site / descriptionPrevious value: -"Job site id, as freeapply_status lists it in sites."New value: +"Job site id, as freeapply_get_status lists it in sites."
- Added
freeapply_share_data - Removed
freeapply_shared_data - Removed
freeapply_status - Changed
freeapply_update_settings1 field changed- changed
Input schema / properties / patch / descriptionPrevious value: -"Fields to change, nested by section with freeapply_get_settings' names, e.g. {\"targets\": {\"min_pay\": 60000}}. resume: only text and profile {headline, skills, titles, education, certifications}, from the résumé text alone. models: the scan {app, current, can_delegate, available, efforts}, read from your own tools; replaces the last scan."New value: +"Fields to change, nested by section."
- Removed
freeapply_user_answers
2 tool updates
v1.0.5- Changed
freeapply_autorun1 field changed- added
Input schema / properties / waitAdded value: +{ + "description": "For start, in a scheduled run: if the user turned auto-run off, wait for them to press Start.", + "type": "boolean" +}
- Changed
freeapply_clear_to_submit1 field changed- changed
Input schema / properties / run_id / descriptionPrevious value: -"Unattended run only: the run_id from freeapply_autorun start; first checks that run's time and application budgets and the dashboard's Stop button."New value: +"Unattended run only: the run_id from freeapply_autorun start; first checks that run's limits and the dashboard's Stop button, and keeps the run alive."
17 tool updates
v1.0.4- Changed
freeapply_autorun3 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"start or finish a run, or report the scheduled task."New value: +"start or finish a run; schedule_created or schedule_removed report the scheduled task." - changed
Input schema / properties / run_id / descriptionPrevious value: -"For finish: the run_id that start returned."New value: +"Required for finish: the run_id start returned." - changed
Input schema / properties / summary / descriptionPrevious value: -"For finish: one line on the run."New value: +"For finish: one line on the run, e.g. \"applied 4, needs you 2\" (up to 500 characters)."
- Changed
freeapply_check_text5 fields changed- changed
Input schema / properties / company / descriptionPrevious value: -"The employer, when there is no job_id. Optional."New value: +"The employer, when there is no job_id." - changed
Input schema / properties / job_id / descriptionPrevious value: -"The job it is for. Optional; needed for save."New value: +"Adds the posting's keywords; numbers from the job's posting, title, pay, location and posting id, and the user's answers for this job, count as facts. Needed for save." - changed
Input schema / properties / kind / descriptionPrevious value: -"What the text is. Optional; default answer."New value: +"cover_letter: also checks the user's length, sign-off, leftover placeholders and that the company is named. answer (default): facts only." - changed
Input schema / properties / save / descriptionPrevious value: -"Save a passing cover letter as a PDF. Optional; default false."New value: +"Save a passing cover letter as a PDF (default false). For a letter, pass it from the first call: checked and saved at once." - changed
Input schema / properties / text / descriptionPrevious value: -"The cover letter or answer to check, exactly as you will type or attach it."New value: +"The letter or answer, exactly as you will type or attach it."
- Changed
freeapply_claim_job13 fields changed- changed
Input schema / properties / apply_url / descriptionPrevious value: -"Where the application form is, if different."New value: +"Application form URL, if different." - changed
Input schema / properties / company / descriptionPrevious value: -"Employer name, as posted (not the staffing firm's name, if known)."New value: +"The employer as posted; not a staffing firm, when you can tell." - changed
Input schema / properties / external_id / descriptionPrevious value: -"The posting's id on its source site; finds the same posting again, reposts included."New value: +"The posting's id on its source site; pass it whenever shown: finds the posting again and catches reposts." - changed
Input schema / properties / fit_notes / descriptionPrevious value: -"Why it fits or doesn't, in one sentence."New value: +"Why it fits or doesn't, one sentence." - changed
Input schema / properties / fit_score / descriptionPrevious value: -"Fit from 0 to 100, scored as the apply procedure describes."New value: +"0-100, scored as the apply procedure says." - changed
Input schema / properties / location / descriptionPrevious value: -"Location as posted."New value: +"As posted." - changed
Input schema / properties / pay_max / descriptionPrevious value: -"Highest posted pay as a number."New value: +"Highest posted pay, a number. Feeds the pay floor." - changed
Input schema / properties / pay_min / descriptionPrevious value: -"Lowest posted pay as a number: annual, or hourly if posted hourly."New value: +"Lowest posted pay, a number: annual, or hourly if posted hourly. Feeds the pay floor." - changed
Input schema / properties / source / descriptionPrevious value: -"Where it was found: a job site id (linkedin, indeed, company_sites, ...) or referral."New value: +"Where found: job site id (linkedin, indeed, company_sites, ...) or referral; tells the job site like url." - changed
Input schema / properties / status / descriptionPrevious value: -"found to work on it (default), or skipped to record a job you won't pursue."New value: +"found (default): to work on; skipped: a job you won't pursue." - changed
Input schema / properties / status_note / descriptionPrevious value: -"Why it was skipped, in one plain sentence; for status skipped."New value: +"For skipped: why, one plain sentence." - changed
Input schema / properties / title / descriptionPrevious value: -"Job title, as posted."New value: +"As posted." - changed
Input schema / properties / url / descriptionPrevious value: -"The posting's URL; also tells which job site it came from."New value: +"Posting URL; tells the job site. The URL just read by freeapply_fetch_posting keeps its keywords."
- Changed
freeapply_clear_to_submit3 fields changed- changed
Input schema / properties / job_id / descriptionPrevious value: -"The job about to be submitted."New value: +"The job about to be submitted; without it you only see the pace." - changed
Input schema / properties / method / descriptionPrevious value: -"How you will submit: external (an employer or ATS form; default), easy_apply (a job board's one-click apply) or email."New value: +"How you will submit: external (employer or ATS form; default), easy_apply (a job board's one-click apply; refused while one-click apply is off) or email." - changed
Input schema / properties / run_id / descriptionPrevious value: -"In an unattended run only: the run_id that freeapply_autorun start returned."New value: +"Unattended run only: the run_id from freeapply_autorun start; first checks that run's time and application budgets and the dashboard's Stop button."
- Changed
freeapply_fetch_posting3 fields changed- changed
Input schema / properties / max_chars / descriptionPrevious value: -"Longest description to return, in characters. Optional; default 6000."New value: +"Description cap in characters (default 6000)." - changed
Input schema / properties / source / descriptionPrevious value: -"The job site id where it was found. Optional."New value: +"Job site id where found, e.g. linkedin; picks the saved answers meant for that site." - changed
Input schema / properties / url / descriptionPrevious value: -"The posting's URL: the job page or its application form."New value: +"The job page or its application form."
- Changed
freeapply_find_site_account1 field changed- changed
Input schema / properties / site / descriptionPrevious value: -"The employer site's domain or any URL on it, e.g. careers.example.com."New value: +"Domain or any URL on it, e.g. careers.example.com; reduced to the domain without www. and matched exactly (careers.example.com and example.com differ)."
- Changed
freeapply_get_settings1 field changed- changed
Input schema / properties / sections / descriptionPrevious value: -"Sections to return. Optional; default all."New value: +"Sections to return (default all), e.g. [\"profile\", \"eligibility\"] for a form; omit resume, the largest, unless you need its text."
- Changed
freeapply_list_jobs5 fields changed- changed
Input schema / properties / limit / descriptionPrevious value: -"Most jobs to return. Optional; default 200."New value: +"Most jobs to return (default 200); fewer returned means the end." - changed
Input schema / properties / offset / descriptionPrevious value: -"Jobs to skip, for the next page. Optional; default 0."New value: +"Jobs to skip, for the next page (default 0)." - changed
Input schema / properties / outcome / descriptionPrevious value: -"Only jobs with this employer outcome. Optional."New value: +"Exact employer-outcome filter." - changed
Input schema / properties / search / descriptionPrevious value: -"Text to find in the title, company or location. Optional."New value: +"Text in the title, company or location, ignoring case." - changed
Input schema / properties / status / descriptionPrevious value: -"Only jobs with this status. Optional."New value: +"Exact status filter."
- Changed
freeapply_open_dashboard1 field changed- changed
Input schema / properties / tab / descriptionPrevious value: -"The page to open. Optional; default overview."New value: +"Page: overview (default; shows the Terms until accepted), settings (setup fields), issues (Needs you: questions, sign-ups), applications, replies."
- Changed
freeapply_record_outcome9 fields changed- changed
Input schema / properties / company / descriptionPrevious value: -"With an email: the employer that sent it."New value: +"Email: the employer that sent it." - changed
Input schema / properties / gmail_thread_id / descriptionPrevious value: -"With an email: Gmail thread id."New value: +"Email: Gmail thread id." - changed
Input schema / properties / job_id / descriptionPrevious value: -"The job it is about."New value: +"From the reply-check plan or freeapply_list_jobs. Required without an email; with one optional, but without it no outcome changes." - changed
Input schema / properties / mail_action / descriptionPrevious value: -"With an email: what you did with it in Gmail."New value: +"Email: what you did with it in Gmail: starred, labeled:<name>, starred+labeled:<name> or none." - changed
Input schema / properties / outcome / descriptionPrevious value: -"What 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."New value: +"What 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 (without an email only)." - changed
Input schema / properties / received_at / descriptionPrevious value: -"With an email: when it arrived (ISO 8601)."New value: +"Email: when it arrived (ISO 8601)." - changed
Input schema / properties / sender / descriptionPrevious value: -"With an email: sender address."New value: +"Email: sender address." - changed
Input schema / properties / subject / descriptionPrevious value: -"With an email: subject line."New value: +"Email: subject line." - changed
Input schema / properties / summary / descriptionPrevious value: -"With an email: one sentence on what it says."New value: +"Email: what it says, one sentence of at most 20 words, no personal data beyond what is needed."
- Changed
freeapply_reply_check4 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"start returns the plan; finish marks the check done."New value: +"start: the plan; read: the mailbox; mark: star or label one email; finish: the check is done." - changed
Input schema / properties / action / enumPrevious value: -[ - "start", - "finish" -]New value: +[ + "start", + "read", + "mark", + "finish" +] - added
Input schema / properties / gmail_message_idAdded value: +{ + "description": "Required for mark: the email's id, from read.", + "type": "string" +} - added
Input schema / properties / kindAdded value: +{ + "description": "Required for mark: the outcome you recorded for the email.", + "enum": [ + "acknowledged", + "replied", + "assessment", + "interview", + "rejected", + "offer", + "withdrawn" + ], + "type": "string" +}
- Changed
freeapply_report_site_problem2 fields changed- changed
Input schema / properties / site / descriptionPrevious value: -"The job site, as listed in freeapply_status sites."New value: +"Job site id, as freeapply_status lists it in sites." - changed
Input schema / properties / status / descriptionPrevious value: -"What the site showed."New value: +"signed_out: a sign-in page, or the site says you're signed out. limit_reached: the site's own daily limit, e.g. \"You reached today's Easy Apply limit\"."
- Changed
freeapply_shared_data1 field changed- changed
Input schema / properties / action / descriptionPrevious value: -"preview shows what would be sent; sync sends it now."New value: +"preview: show what would be sent; sync: send it now."
- Changed
freeapply_status2 fields changed- added
Input schema / properties / laneAdded value: +{ + "description": "A helper's lane of freeapply-apply: only the hard rules and that lane's steps, with a short status. Optional; the agent that starts helpers omits it.", + "enum": [ + "scout", + "writer", + "applier" + ], + "type": "string" +} - changed
Input schema / properties / procedure / descriptionPrevious value: -"The task whose procedure to include. Optional."New value: +"Adds this task's procedure: freeapply-setup (first run; Terms or settings missing), freeapply-apply (find jobs, apply), freeapply-replies (Gmail reply check). Omit for status only."
- Changed
freeapply_update_job13 fields changed- changed
Input schema / properties / account_url / descriptionPrevious 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."New value: +"needs_account only: the site's sign-up page. Jobs with the same one share a card; one \"I made the account\" re-queues them all. Default: the application link, so jobs rarely share." - changed
Input schema / properties / confirmation / descriptionPrevious value: -"For applied: the confirmation text or number the site showed."New value: +"applied only: the confirmation text or number the site showed." - changed
Input schema / properties / cover_path / descriptionPrevious value: -"For applied: the cover-letter file sent, if not the saved one. Optional."New value: +"applied only: the letter file sent, if not the saved one." - changed
Input schema / properties / cover_text / descriptionPrevious value: -"For applied: the cover letter sent, if not the saved one. Optional."New value: +"applied only: the letter sent, if not the saved one." - added
Input schema / properties / letter_sentAdded value: +{ + "description": "applied only; required when a letter is saved for the job (freeapply_check_text save): true if attached or pasted, false if not (letter dropped from the record).", + "type": "boolean" +} - changed
Input schema / properties / method / descriptionPrevious value: -"For applied: how it was submitted."New value: +"applied only: how it was submitted." - changed
Input schema / properties / note / descriptionPrevious value: -"What happened, for the user, e.g. \"The site asked to prove you're a person.\""New value: +"What happened, for the user: one plain sentence, no technical terms, e.g. \"The site asked to prove you're a person.\"" - changed
Input schema / properties / questions / descriptionPrevious value: -"For needs_info: the form's unanswered questions, each with a plain prompt and the simplest kind of answer that fits."New value: +"needs_info only, at least one: the form's unanswered questions, each with a plain prompt and the simplest kind of answer that fits." - changed
Input schema / properties / questions / items / properties / label / descriptionPrevious value: -"The question exactly as the form words it (you need it to fill the form later)."New value: +"Exactly as the form words it (needed to fill the form later)." - changed
Input schema / properties / questions / items / properties / options / descriptionPrevious value: -"Choices, for choice or multi, worded as the form offers them."New value: +"For choice or multi: the choices as the form words them." - changed
Input schema / properties / questions / items / properties / prompt / descriptionPrevious value: -"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)*\"."New value: +"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)*\"." - changed
Input schema / properties / questions / items / properties / type / descriptionPrevious 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."New value: +"yesno or choice: one fixed answer (buttons up to 5 options, else a dropdown); multi: all that apply; number; date; text or textarea." - changed
Input schema / properties / resume_path / descriptionPrevious value: -"For applied: the résumé file sent, if not the documents copy. Optional."New value: +"applied only: the résumé file sent, if not the documents copy (recorded by default)."
- Changed
freeapply_update_settings1 field changed- changed
Input schema / properties / patch / descriptionPrevious value: -"The fields to change, nested by section, e.g. {\"profile\": {\"phone\": \"+1 555 0100\"}}."New value: +"Fields to change, nested by section with freeapply_get_settings' names, e.g. {\"targets\": {\"min_pay\": 60000}}. resume: only text and profile {headline, skills, titles, education, certifications}, from the résumé text alone. models: the scan {app, current, can_delegate, available, efforts}, read from your own tools; replaces the last scan."
- Changed
freeapply_user_answers4 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"get a job's answers, or save one reusable answer."New value: +"get: a job's answers and saved letter; save: one reusable answer." - changed
Input schema / properties / answer / descriptionPrevious value: -"For save: the user's answer in their own words; empty to remove a saved answer."New value: +"For save: the user's own words; empty removes the saved answer." - changed
Input schema / properties / job_id / descriptionPrevious value: -"For get: the job whose answers you need."New value: +"Required for get." - changed
Input schema / properties / label / descriptionPrevious value: -"For save: the question, worded as forms ask it, e.g. \"Are you willing to relocate?\"."New value: +"Required for save: the question as forms word it, e.g. \"Are you willing to relocate?\"."
26 tool updates
v1.0.2- Removed
freeapply_add_job - Removed
freeapply_answers - Changed
freeapply_autorun4 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"What to do."New value: +"start or finish a run, or report the scheduled task." - changed
Input schema / properties / action / enumPrevious value: -[ - "start", - "check", - "finish", - "schedule_created", - "schedule_removed" -]New value: +[ + "start", + "finish", + "schedule_created", + "schedule_removed" +] - changed
Input schema / properties / run_id / descriptionPrevious value: -"The run_id that start returned; needed for check and finish."New value: +"For finish: the run_id that start returned." - changed
Input schema / properties / summary / descriptionPrevious value: -"One-line summary, for finish."New value: +"For finish: one line on the run."
- Removed
freeapply_check_duplicate - Changed
freeapply_check_text4 fields changed- changed
Input schema / properties / company / descriptionPrevious 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." - changed
Input schema / properties / job_id / descriptionPrevious 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." - added
Input schema / properties / saveAdded value: +{ + "description": "Save a passing cover letter as a PDF. Optional; default false.", + "type": "boolean" +} - changed
Input schema / properties / text / descriptionPrevious 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."
- Added
freeapply_claim_job - Added
freeapply_clear_to_submit - Changed
freeapply_fetch_posting1 field changed- changed
Input schema / properties / source / descriptionPrevious 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."
- Added
freeapply_find_site_account - Changed
freeapply_get_settings1 field changed- added
Input schema / properties / sectionsAdded value: +{ + "description": "Sections to return. Optional; default all.", + "items": { + "type": "string" + }, + "type": "array" +}
- Removed
freeapply_get_stats - Added
freeapply_job_stats - Changed
freeapply_open_dashboard1 field changed- changed
Input schema / properties / tab / descriptionPrevious value: -"Tab to show. Optional; default overview."New value: +"The page to open. Optional; default overview."
- Added
freeapply_record_outcome - Removed
freeapply_record_reply - Added
freeapply_report_site_problem - Removed
freeapply_save_resume - Removed
freeapply_set_outcome - Removed
freeapply_site_account - Removed
freeapply_site_status - Changed
freeapply_status1 field changed- added
Input schema / properties / procedureAdded value: +{ + "description": "The task whose procedure to include. Optional.", + "enum": [ + "freeapply-setup", + "freeapply-apply", + "freeapply-replies" + ], + "type": "string" +}
- Removed
freeapply_throttle - Changed
freeapply_update_job10 fields changed- changed
Input schema / properties / account_url / descriptionPrevious 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." - changed
Input schema / properties / confirmation / descriptionPrevious value: -"Confirmation text or number the site showed."New value: +"For applied: the confirmation text or number the site showed." - changed
Input schema / properties / cover_path / descriptionPrevious value: -"Path of the cover-letter file submitted."New value: +"For applied: the cover-letter file sent, if not the saved one. Optional." - changed
Input schema / properties / cover_text / descriptionPrevious 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." - changed
Input schema / properties / job_id / descriptionPrevious 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." - changed
Input schema / properties / method / descriptionPrevious value: -"How it was submitted, for applied."New value: +"For applied: how it was submitted." - changed
Input schema / properties / note / descriptionPrevious 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.\"" - changed
Input schema / properties / questions / descriptionPrevious 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." - changed
Input schema / properties / questions / items / properties / type / descriptionPrevious 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." - changed
Input schema / properties / resume_path / descriptionPrevious value: -"Path of the résumé file submitted."New value: +"For applied: the résumé file sent, if not the documents copy. Optional."
- Changed
freeapply_update_settings1 field changed- changed
Input schema / properties / patch / descriptionPrevious 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\"}}."
- Added
freeapply_user_answers - Removed
freeapply_workflow
26 tool updates
v1.0.1- Changed
freeapply_add_job19 fields changed- added
Input schema / properties / apply_url / descriptionAdded value: +"Where the application form is, if different." - added
Input schema / properties / company / descriptionAdded value: +"Employer name." - added
Input schema / properties / description / descriptionAdded value: +"Short description or key requirements." - changed
Input schema / properties / external_id / descriptionPrevious value: -"posting id on the source site"New value: +"The posting's id on its source site, used to spot reposts." - added
Input schema / properties / fit_notes / descriptionAdded value: +"Why it fits or doesn't, in a sentence." - added
Input schema / properties / fit_score / descriptionAdded value: +"Fit from 0 to 100, as the procedure describes." - added
Input schema / properties / fit_score / maximumAdded value: +100 - added
Input schema / properties / fit_score / minimumAdded value: +0 - added
Input schema / properties / location / descriptionAdded value: +"Location as posted." - added
Input schema / properties / pay_max / descriptionAdded value: +"Highest posted pay as a number." - added
Input schema / properties / pay_min / descriptionAdded value: +"Lowest posted pay as a number (annual, or hourly if posted hourly)." - added
Input schema / properties / pay_text / descriptionAdded value: +"Pay exactly as posted, e.g. \"$90k-$110k\"." - changed
Input schema / properties / source / descriptionPrevious value: -"linkedin, company_site, indeed, referral, ..."New value: +"Where it was found: a job site id (linkedin, indeed, company_sites, ...) or referral." - added
Input schema / properties / status / descriptionAdded value: +"found to work on it (default), skipped to record a job that doesn't fit." - added
Input schema / properties / status / enumAdded value: +[ + "found", + "skipped" +] - added
Input schema / properties / status_note / descriptionAdded value: +"Reason, for a skipped job." - added
Input schema / properties / title / descriptionAdded value: +"Job title." - added
Input schema / properties / url / descriptionAdded value: +"The posting's URL." - added
Input schema / properties / work_mode / descriptionAdded value: +"remote, hybrid or onsite, as posted."
- Added
freeapply_answers - Changed
freeapply_autorun4 fields changed- added
Input schema / properties / action / descriptionAdded value: +"What to do." - added
Input schema / properties / action / enumAdded value: +[ + "start", + "check", + "finish", + "schedule_created", + "schedule_removed" +] - added
Input schema / properties / run_id / descriptionAdded value: +"The run_id that start returned; needed for check and finish." - added
Input schema / properties / summary / descriptionAdded value: +"One-line summary, for finish."
- Changed
freeapply_check_duplicate3 fields changed- added
Input schema / properties / company / descriptionAdded value: +"Employer name as shown in the posting." - added
Input schema / properties / external_id / descriptionAdded value: +"The posting's id on its source site. Optional; also finds the exact posting." - added
Input schema / properties / title / descriptionAdded value: +"Job title. Optional; marks matches with the same title."
- Changed
freeapply_check_text6 fields changed- added
Input schema / properties / company / descriptionAdded value: +"The employer it is addressed to. Optional; a cover letter that never mentions it is flagged." - added
Input schema / properties / job_id / descriptionAdded value: +"The job it is for. Optional; numbers from its posting and the user's answers for it then count as supported." - added
Input schema / properties / job_id / minimumAdded value: +1 - added
Input schema / properties / kind / descriptionAdded value: +"What the text is. Optional; default answer." - added
Input schema / properties / kind / enumAdded value: +[ + "cover_letter", + "answer" +] - added
Input schema / properties / text / descriptionAdded value: +"The cover letter or answer to check."
- Changed
freeapply_fetch_posting5 fields changed- added
Input schema / properties / max_chars / defaultAdded value: +6000 - added
Input schema / properties / max_chars / descriptionAdded value: +"Longest description to return, in characters. Optional; default 6000." - added
Input schema / properties / max_chars / minimumAdded value: +500 - added
Input schema / properties / source / descriptionAdded value: +"Where the posting was found, as a job site id (linkedin, indeed, company_sites, ...). Optional; helps pick suggested answers." - added
Input schema / properties / url / descriptionAdded value: +"The posting's URL: the job page or its application form."
- Removed
freeapply_finish_reply_check - Removed
freeapply_get_answers - Changed
freeapply_list_jobs10 fields changed- added
Input schema / properties / limit / defaultAdded value: +200 - added
Input schema / properties / limit / descriptionAdded value: +"Most jobs to return. Optional; default 200." - added
Input schema / properties / limit / maximumAdded value: +2000 - added
Input schema / properties / limit / minimumAdded value: +1 - added
Input schema / properties / offsetAdded value: +{ + "default": 0, + "description": "Jobs to skip, for the next page. Optional; default 0.", + "minimum": 0, + "type": "integer" +} - added
Input schema / properties / outcome / descriptionAdded value: +"Only jobs with this employer outcome. Optional." - added
Input schema / properties / outcome / enumAdded value: +[ + "acknowledged", + "replied", + "assessment", + "interview", + "rejected", + "offer", + "withdrawn" +] - added
Input schema / properties / search / descriptionAdded value: +"Text to find in the title, company or location. Optional." - added
Input schema / properties / status / descriptionAdded value: +"Only jobs with this status. Optional." - added
Input schema / properties / status / enumAdded value: +[ + "found", + "ready", + "applied", + "skipped", + "needs_info", + "needs_account", + "blocked", + "failed" +]
- Changed
freeapply_open_dashboard2 fields changed- added
Input schema / properties / tab / descriptionAdded value: +"Tab to show. Optional; default overview." - added
Input schema / properties / tab / enumAdded value: +[ + "overview", + "applications", + "replies", + "issues", + "settings" +]
- Removed
freeapply_preview_shared_data - Changed
freeapply_record_reply12 fields changed- added
Input schema / properties / company / descriptionAdded value: +"The employer that sent it." - added
Input schema / properties / gmail_message_id / descriptionAdded value: +"Gmail message id; prevents recording it twice." - added
Input schema / properties / gmail_thread_id / descriptionAdded value: +"Gmail thread id." - added
Input schema / properties / job_id / descriptionAdded value: +"The job the email is about. Optional, but without it no outcome changes." - added
Input schema / properties / job_id / minimumAdded value: +1 - added
Input schema / properties / kind / descriptionAdded 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)." - added
Input schema / properties / kind / enumAdded value: +[ + "acknowledged", + "replied", + "assessment", + "interview", + "rejected", + "offer", + "withdrawn" +] - added
Input schema / properties / mail_action / descriptionAdded value: +"What you did with it in Gmail: starred, labeled:<name>, starred+labeled:<name> or none." - added
Input schema / properties / received_at / descriptionAdded value: +"When it arrived (ISO 8601)." - added
Input schema / properties / sender / descriptionAdded value: +"Sender address." - added
Input schema / properties / subject / descriptionAdded value: +"Subject line." - added
Input schema / properties / summary / descriptionAdded value: +"One sentence on what the email says (at most 20 words, no personal data beyond what is needed)."
- Added
freeapply_reply_check - Removed
freeapply_reply_check_plan - Added
freeapply_save_resume - Removed
freeapply_save_resume_profile - Removed
freeapply_save_resume_text - Changed
freeapply_set_outcome4 fields changed- added
Input schema / properties / job_id / descriptionAdded value: +"The job's id, as returned by freeapply_add_job or freeapply_list_jobs." - added
Input schema / properties / job_id / minimumAdded value: +1 - added
Input schema / properties / outcome / descriptionAdded 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." - added
Input schema / properties / outcome / enumAdded value: +[ + "acknowledged", + "replied", + "assessment", + "interview", + "rejected", + "offer", + "withdrawn", + "" +]
- Added
freeapply_shared_data - Changed
freeapply_site_account1 field changed- added
Input schema / properties / site / descriptionAdded value: +"The employer site's domain or any URL on it, e.g. careers.example.com or the application form's URL."
- Changed
freeapply_site_status4 fields changed- changed
Input schema / properties / site / descriptionPrevious value: -"linkedin, indeed, glassdoor, ziprecruiter, dice, wellfound, handshake, company_sites"New value: +"The job site." - added
Input schema / properties / site / enumAdded value: +[ + "linkedin", + "indeed", + "glassdoor", + "ziprecruiter", + "dice", + "wellfound", + "handshake", + "company_sites" +] - added
Input schema / properties / status / descriptionAdded value: +"What the site showed." - added
Input schema / properties / status / enumAdded value: +[ + "signed_out", + "limit_reached" +]
- Removed
freeapply_sync_shared_data - Changed
freeapply_throttle4 fields changed- added
Input schema / properties / job_id / descriptionAdded value: +"The job's id, as returned by freeapply_add_job or freeapply_list_jobs." - added
Input schema / properties / job_id / minimumAdded value: +1 - added
Input schema / properties / method / descriptionAdded value: +"How you will submit. Optional; default external (an employer or ATS form)." - added
Input schema / properties / method / enumAdded value: +[ + "external", + "easy_apply", + "email" +]
- Changed
freeapply_update_job15 fields changed- added
Input schema / properties / account_urlAdded 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" +} - added
Input schema / properties / confirmation / descriptionAdded value: +"Confirmation text or number the site showed." - added
Input schema / properties / cover_path / descriptionAdded value: +"Path of the cover-letter file submitted." - added
Input schema / properties / cover_text / descriptionAdded value: +"The cover letter actually submitted; it must pass the truthfulness check." - added
Input schema / properties / job_id / descriptionAdded value: +"The job's id, as returned by freeapply_add_job or freeapply_list_jobs." - added
Input schema / properties / job_id / minimumAdded value: +1 - added
Input schema / properties / method / descriptionAdded value: +"How it was submitted, for applied." - added
Input schema / properties / method / enumAdded value: +[ + "easy_apply", + "external", + "email" +] - added
Input schema / properties / note / descriptionAdded 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.\"" - added
Input schema / properties / questions / descriptionAdded 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." - added
Input schema / properties / questions / items / propertiesAdded 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" + } +} - added
Input schema / properties / questions / items / requiredAdded value: +[ + "label" +] - added
Input schema / properties / resume_path / descriptionAdded value: +"Path of the résumé file submitted." - added
Input schema / properties / status / descriptionAdded 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)." - added
Input schema / properties / status / enumAdded value: +[ + "found", + "ready", + "applied", + "skipped", + "needs_info", + "needs_account", + "blocked", + "failed" +]
- Changed
freeapply_update_settings1 field changed- added
Input schema / properties / patch / descriptionAdded 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."
- Changed
freeapply_workflow2 fields changed- added
Input schema / properties / name / descriptionAdded value: +"Procedure to get. Optional; omit to list the procedures." - added
Input schema / properties / name / enumAdded value: +[ + "freeapply-setup", + "freeapply-apply", + "freeapply-replies" +]
25 tool updates
v0.1.0- First observed
freeapply_add_job - First observed
freeapply_autorun - First observed
freeapply_check_duplicate - First observed
freeapply_check_text - First observed
freeapply_fetch_posting - First observed
freeapply_finish_reply_check - First observed
freeapply_get_answers - First observed
freeapply_get_settings - First observed
freeapply_get_stats - First observed
freeapply_list_jobs - First observed
freeapply_open_dashboard - First observed
freeapply_preview_shared_data - First observed
freeapply_record_reply - First observed
freeapply_reply_check_plan - First observed
freeapply_save_resume_profile - First observed
freeapply_save_resume_text - First observed
freeapply_set_outcome - First observed
freeapply_site_account - First observed
freeapply_site_status - First observed
freeapply_status - First observed
freeapply_sync_shared_data - First observed
freeapply_throttle - First observed
freeapply_update_job - First observed
freeapply_update_settings - First observed
freeapply_workflow
TDQS
Scored across 18 tools
Each tool targets a distinct slice of the workflow (claim, update, list, stats, settings, replies, autorun, sharing), and descriptions carry explicit 'not for X, use Y' routing that preempts most confusion. The job lifecycle is deliberately split across claim_job/update_job/record_outcome/clear_to_submit, which an agent must learn, and several tools bundle multi-action parameters (get/save, start/read/mark/finish, preview/sync) that add internal selection burden.
All 18 names are uniformly snake_case with a consistent freeapply_ prefix, so the set is easy to scan and group. A few verbs are weaker than others (manage_autorun, manage_answers are generic; clear_to_submit is not a clean verb_noun phrase), but no convention mixing.
18 tools is slightly above the comfortable band, but the domain is genuinely broad (job lifecycle, settings, autorun sessions, email replies, site accounts, data sharing). Each tool maps to a real distinct operation, though a couple of the multi-action tools could be consolidated.
Coverage is strong: claim, update, list, stats, settings read/write, posting fetch, text verification, saved answers, submit clearance, site-signin handling, reply checking, outcome recording, and sharing are all present. Remaining gaps (deleting/untracking a job, résumé management, job search) are explicit and deliberately delegated to the dashboard or the browser, so agents can work around them.
Maintenance
Related MCP Connectors
searchnapply connects your AI agent to 800K+ open jobs taken straight from company career sites, kept up to date as companies add and close them. Search in your own words with the site's filters (role, location, remote, salary, experience, department), read postings in full, and tailor a resume or cover letter from your searchnapply profile. Save a search as a monitor to collect new postings and track what you applied to or skipped. It never invents a job or a salary, and it does not apply for you: you apply on the company's own page. Free plan included, within a daily call limit.
Job application tracker for developers - AI agents write over MCP, you review in a dashboard.
Tailor resumes, score ATS fit, find hiring leads, and send cold outreach, from your agent.
Auto-apply to jobs: matches your CV, tailors a fresh CV per posting, and applies for you.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables 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.37MIT
- FlicenseNot gradedqualityDmaintenanceEnables 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.-
- FlicenseAqualityCmaintenanceEnables an LLM client to read a structured CV resource and send tailored application emails to recruiters via SMTP.1-
- FlicenseNot gradedqualityBmaintenanceEnables 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.-