Harness-agnostic auto-apply: browser hands + a learning memory, exposed as an MCP server
Strong tool design with clear naming (verb_noun pattern), comprehensive descriptions (avg 180 chars), and well-structured schemas. All 24 tools have explicit input schemas with typed parameters and descriptions. Notable strengths: role/reason parameters enforce audit trails (pattern:command-tool), preflight/confirmation gates prevent irreversible mistakes (pattern:confirmation-request), error responses include actionable guidance (e.g., browser_busy with holder info). Weaknesses: output schemas documented in prose but not formally in JSON Schema; some descriptions lack dependency hints; no explicit enum constraints for categorical fields (e.g., direction in browser_scroll accepts 'down'|'up' but not declared as enum).
Close the automation browser and release the profile lock.
Open a URL in the automation browser. The browser launches on first use with a persistent profile, so a LinkedIn session established once is reused on later runs. Only one process may drive that profile at a time -- two Chromes on one profile delete each other's cookies, and the logged-in session cannot be rebuilt from here. If another driver (the scheduled loop, a batch run) has it, this returns `browser_busy: true` with the holder's name instead of opening a second browser. Do not retry in a loop; the holder is usually mid-application.
Save a screenshot of the visible viewport and return its path. Use this when the field list looks wrong or empty: the DOM can be read literally, but only a picture shows whether the page is where you think it is.
Scroll the viewport. `direction` is 'down' or 'up'.
List the current page's form fields, buttons and tabs. Every field carries a `ref` string. Pass that same `ref` back to `fill_field` / `select_option` / `click_target`; do not construct your own CSS selector, because the references are already chosen to survive the site's generated markup. Fields with `required: true` must be filled before submitting. `field_type` tells you which action to use: - text/email/tel/number/textarea/contenteditable -> fill_field - select/combobox/listbox -> select_option - radio/checkbox -> set_checkbox - file -> upload_file
Output schemas documented in prose but not formally declared in JSON Schema. Tools return JSON strings with documented fields (e.g., discover_jobs returns search_url, count, jobs) but no explicit schema definition for LLM parsing.
Categorical parameters lack enum constraints. browser_scroll direction accepts 'down'|'up' but is typed as string without enum. LLMs may hallucinate invalid values.
Some descriptions lack dependency hints or context about when to call tools. E.g., browser_tabs and browser_switch_tab lack guidance on typical usage patterns.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 64 | 2026-07-28+ | v2 |
Make another tab the active one, by index from `browser_tabs`.
List open tabs. A click may open a second tab (employer ATS sites).
Click a button or link on the page.
Search LinkedIn for postings, newest first. Use this when the user wants jobs *found* rather than handed a link. Defaults to Easy Apply only, because that is the route this server can actually finish; "Apply on company site" hands off to an ATS whose form we have never seen. Returns the postings plus the exact `search_url` used, so a surprising result can be traced back to the query that produced it. This applies to nothing. It only lists. Take a `job_id` or `url` from the result and run the normal `preflight` -> apply flow on it.
Fill a text field with a value, recording the outcome against the platform's selector memory.
Show memory flywheel health: how much is automated vs. needs human input.
Query the memory for an answer to a question. Returns the answer directly if confident, or a suggestion/need_human status.
Check that the ApplyOps server is reachable.
Check if an application is allowed before proceeding. Enforces rate limits and guardrails.
Record a user-provided answer to a question in memory.
Report a failed application attempt with details about where it failed.
Request confirmation before submitting an application, with a summary of all fields and values.
Determine the application route (easy_apply or external_ats) for a job posting.
Save user profile answers from the questionnaire.
Select an option from a dropdown/select field.
Set a checkbox or radio button to checked or unchecked.
Check the setup status and return the questionnaire if not ready.
Submit an application after receiving confirmation.
Upload a file to a file input field.
No explicit error classification (retryable vs user-fixable vs fatal). While browser_busy is well-handled, other tools lack structured error responses with recovery guidance.
Numeric parameters lack explicit min/max constraints. discover_jobs limit defaults to 25 but no bounds stated; recent_days defaults to 0 with no range documented.