Mmcp.market

Workopia — Job Search MCP server

by workopia·io.github.workopia/workopia-mcp·v1.0.2

Search 6.3M+ live jobs from companies' own career pages, plus resume tailoring & cover letters.

B77/100grade B
What users say
No reviews yet
Be the first
Safety scan
B77/100

full report

Adoption
Growing

316 stars

Reviews

Write one

Nobody has reviewed Workopia — Job Search yet.

If you have run it, two minutes of your experience saves the next person an afternoon.

Workopia — Job Search tools (5, 1 write)

write = sends, deletes, buys or posts
  • cover_letter_toolwrite actionFree

    Write a cover letter for a SPECIFIC job — TWO steps. STEP 1 (default; action omitted or 'prepare'): the server returns the job's JD and the candidate's background, plus writing instructions. YOU (the model) then WRITE the cover letter (250–350 words, specific to the role, mapping the candidate's real achievements to the JD — never fabricate). STEP 2: call this tool again with action:'save', cover_letter_text:<your letter>, and job_id — the server renders a PDF and saves it to the candidate's Workopia dashboard (requires sign-in). Use whenever the user asks for a cover letter for a specific job. Resolving job_id (same rules as tailor_resume_tool / job_detail_tool): pass the **Job Id** value from the most recent prior search/refine result VERBATIM; no placeholders like 'JOB_1' or '#1'. For STEP 1 supply ONE of job_id (preferred — server fetches the JD from Mongo) OR job_description, plus the candidate's resume via resume_text / resume_content / json_resume / user_profile.

  • dashboard_toolFree

    Show the signed-in user's Workopia dashboard (saved, tailored, and applied jobs + latest resume). Requires OAuth. Default action is list; optional status_filter (all | saved | tailored | applied). Use whenever the user asks to recall their Workopia activity: 'my applications', 'what jobs have I saved / applied to / tailored', 'show my dashboard', 'where did I leave off'. Returns a secure link to open the full dashboard on the web.

  • job_detail_toolFree

    Render the full job-detail card for a specific job the user asks about. Use this whenever the user references a particular job from a prior search result — by number (#1, '1', 'first', 'the 3rd one', 'job 3'), by company name (partial or full, e.g. 'Morgan Stanley', 'Morstan'), by role/title phrase ('the analyst role', 'the credit risk one'), or by any 'show me this job' / 'tell me more about X' / 'view this role' style request. Resolving job_id from user reference: identify the right job from the most recent prior search/refine result (the numbered list you generated): (a) numeric/ordinal → the Nth job; (b) company name → substring match on Company field; (c) role/title phrase → substring match on Job Title field. Then pass that job's **Job Id** value from the prior search result's content text VERBATIM as job_id. Do NOT use a placeholder like 'JOB_1', '#1', or any synthetic id — only the real **Job Id** string from the prior result is server-valid. Required: job_id. OUTPUT BEHAVIOR: Render the response as a structured markdown card with the job's title (linked to the apply URL), company, location, salary, employment type, work mode, must-have skills, key requirements, highlights, and summary. Follow it with a brief next-step hint (e.g. 'Want to save it, find similar roles, ask about the company, or tailor your resume for this role?').

  • job_toolFree

    Search jobs across 90+ countries by title, location, salary, remote/hybrid work mode, or employment type. Find roles in tech, finance, product, design, marketing, and every other vertical — aggregated from 1000+ ATS sources globally. Default action is search; use refine when the user asks for more matches or gives feedback on a prior result set; use save to bookmark a job for the signed-in user (requires OAuth). REFINE PROTOCOL (action=refine has THREE distinct modes): (1) Pure continuation / 'show me more' / 'next batch' / 'another set' / 'more like these': pass refine_recommendations.exclude_ids = the full array of **Job Id** values from the most recent search/refine result's content text (verbatim) + refine_recommendations.session_id = prior response's session_id if present. Server returns next 10 unique jobs. (2) 'Show me more like #N' / 'similar to the Atlassian one' / 'jobs like #2': pass refine_recommendations.liked_indexes = [N] (1-based position from prior numbered list) + exclude_ids + session_id. Equivalently you may pass refine_recommendations.liked_job_ids = [<that job's **Job Id** value verbatim>]. Server seeds the recommendation from that job's title/skills/company profile. (3) 'Less like #N' / 'no more N-style jobs' / 'avoid jobs like that': pass refine_recommendations.disliked_indexes = [N] (or disliked_job_ids = [<Job Id>]) + exclude_ids + session_id. Server suppresses similar jobs. All three modes: if you skip exclude_ids, the user sees duplicates — that's a failure. The handler layers exclude_ids with server-side AgentKit memory, so partial lists still work. NEVER invent 'JOB_1' / '#1' as job_id values — always use the real **Job Id** string from the prior result's content text. For detail requests (user asks about a specific job from the list, e.g. 'details for #1', 'show me this job', 'tell me more about <company>'), DO NOT call this tool — call job_detail_tool instead. That separate tool binds to the job-detail widget card so the full job card renders in chat. OUTPUT BEHAVIOR: Render the search results as a numbered markdown list, one line per job, in this exact compact format: `N. **[Job Title](View_Job_URL)** — Company · Location · Job Type · Compensation · Posted MMM DD`. Embed the View Job URL as a markdown link on the title (so the user can click to apply). Keep URLs intact — don't strip parameters. Skip a field entirely if it's missing — never print 'N/A' placeholders. The numbered list IS the canonical user-facing answer. REQUIRED follow-up: after the list, output EXACTLY these two sentences as two parallel questions (same pattern for action=search and action=refine): Sentence 1 — 'Would you like to see full details on any of these? Reply with the number (#1), the company name, or the role title.' Sentence 2 — 'Or would you like to refine the list — what should change (work mode, level, salary, sector)?' These two sentences must be separate and parallel; do NOT merge them into one 'detail ... or refine' clause (that buries the detail CTA). Both questions must be asked every time after a search or refine result. When the user replies referring to a specific job from the list, identify which job they mean and call job_detail_tool immediately. Identifying the job (use flexibly — users rarely type '#N' literally): (a) any numeric or ordinal reference ('#1', '1', 'first', 'the 1st', 'top one', 'job 3', 'the third') → the Nth job in your prior numbered list; (b) a company name, partial or full ('Morgan Stanley', 'Morstan', 'Capital One') → case-insensitive substring match on the Company field of the prior list, pick the first match; (c) a role/title phrase ('the analyst role', 'the credit risk one') → case-insensitive substring match on the Job Title field. If multiple jobs match, prefer the earliest. Only if no reasonable match exists, ask a one-line clarifying question. Then pass that job's **Job Id** value from the prior search result's content text VERBATIM as job_id to job_detail_tool / tailor_resume_tool / cover_letter_tool. Do NOT invent a placeholder like 'JOB_1' or '#1' — those are not server-valid IDs. For save, pass job_id + optional job_title/company/job_url in save_job. Put search fields in search_jobs or parameters; refine in refine_recommendations; save in save_job.

  • tailor_resume_toolFree

    Tailor a resume to a SPECIFIC job — TWO steps. STEP 1 (default; action omitted or 'prepare'): the server returns the job's full JD, its must-have skills/requirements, and the candidate's current resume, plus tailoring instructions. YOU (the model) then WRITE the tailored resume as JSON Resume, following the instructions — weave JD keywords into existing bullets only where the candidate genuinely has the experience, never fabricate experience/titles/dates/employers, keep all dates and company names, and flag any keyword you couldn't honestly add. STEP 2: call this tool again with action:'save', tailored_resume:<your JSON Resume>, and job_id — the server renders a PDF and saves it to the candidate's Workopia dashboard (requires sign-in). Use whenever the user references a specific job to tailor for: 'tailor for #1', 'for Morgan Stanley', 'tailor my resume for this role: <JD>'. Resolving job_id (same rules as job_detail_tool): from the most recent prior search/refine result — (a) numeric/ordinal → the Nth job; (b) company name → Company-field match; (c) role/title phrase → Job-Title match — then pass that job's **Job Id** value VERBATIM. Do NOT use placeholders like 'JOB_1' or '#1'. For STEP 1 supply ONE of job_id (preferred — server fetches the JD from Mongo) OR job_description, plus the candidate's resume via resume_text / resume_content / resume_data. For general 'improve my resume' (no specific job), do NOT call this tool — call resume_tool action=improve instead. Note: the tailored resume is written by your AI client's own model — the assistant you are already using — so it works out of the box with nothing to configure; Workopia runs no LLM of its own and never charges for the AI.

Public scan report

scanner v0.1.9 · 2026-09-27 · same rubric, same numbers if you re-run it

1 high1 low
  • –Code scanremote-only server, no package to scann/a
  • Live reliabilityremote reachable in 282ms20/20
  • Tool poisoning5 tool descriptions checked13/15
  • Auth qualityopen endpoint exposes 1 write-action tools with no auth3/15
  • Maintenancelast push 27 days ago15/15
  • Maintainer identityregistry namespace matches repository owner7/10

Findings (2)

  • highWrite-action tools reachable without authenticationauth.open-write
  • lowUnusually long tool description (over 2,000 characters)poison.long-description
    tool job_tool: …Search jobs across 90+ countries by title, location, salary, remote/hybrid work mode, or employment type. Find roles in tech, finance, product, design, marketing, and every other vertical — aggregated from 1000+ ATS sources globally. Default action is search; use refine when the user asks for more matches or gives feedback on a prior result set; use save to bookmark a job for the signed-in user (requires OAuth). REFINE PROTOCOL (action=refine has THREE distinct modes): (1) Pure continuation / 'show me more' / 'next batch' / 'another set' / 'more like these': pass refine_recommendations.exclude_ids = the full array of **Job Id** values from the most recent search/refine result's content text (verbatim) + refine_recommendations.session_id = prior response's session_id if present. Server returns next 10 unique jobs. (2) 'Show me more like #N' / 'similar to the Atlassian one' / 'jobs like #2': pass refine_recommendations.liked_indexes = [N] (1-based position from prior numbered list) + exclude_ids + session_id. Equivalently you may pass refine_recommendations.liked_job_ids = [<that job's **Job Id** value verbatim>]. Server seeds the recommendation from that job's title/skills/company profile. (3) 'Less like #N' / 'no more N-style jobs' / 'avoid jobs like that': pass refine_recommendations.disliked_indexes = [N] (or disliked_job_ids = [<Job Id>]) + exclude_ids + session_id. Server suppresses similar jobs. All three modes: if you skip exclude_ids, the user sees duplicates — that's a failure. The handler layers exclude_ids with server-side AgentKit memory, so partial lists still work. NEVER invent 'JOB_1' / '#1' as job_id values — always use the real **Job Id** string from the prior result's content text. For detail requests (user asks about a specific job from the list, e.g. 'details for #1', 'show me this job', 'tell me more about <company>'), DO NOT call this tool — call job_detail_tool instead. That separate tool binds to the job-detail widget card so the full job card renders in chat. OUTPUT BEHAVIOR: Render the search results as a numbered markdown list, one line per job, in this exact compact format: `N. **[Job Title](View_Job_URL)** — Company · Location · Job Type · Compensation · Posted MMM DD`. Embed the View Job URL as a markdown link on the title (so the user can click to apply). Keep URLs intact — don't strip parameters. Skip a field entirely if it's missing — never print 'N/A' placeholders. The numbered list IS the canonical user-facing answer. REQUIRED follow-up: after the list, output EXACTLY these two sentences as two parallel questions (same pattern for action=search and action=refine): Sentence 1 — 'Would you like to see full details on any of these? Reply with the number (#1), the company name, or the role title.' Sentence 2 — 'Or would you like to refine the list — what should change (work mode, level, salary, sector)?' These two sentences must be separate and parallel; do NOT merge them into one 'detail ... or refine' clause (that buries the detail CTA). Both questions must be asked every time after a search or refine result. When the user replies referring to a specific job from the list, identify which job they mean and call job_detail_tool immediately. Identifying the job (use flexibly — users rarely type '#N' literally): (a) any numeric or ordinal reference ('#1', '1', 'first', 'the 1st', 'top one', 'job 3', 'the third') → the Nth job in your prior numbered list; (b) a company name, partial or full ('Morgan Stanley', 'Morstan', 'Capital One') → case-insensitive substring match on the Company field of the prior list, pick the first match; (c) a role/title phrase ('the analyst role', 'the credit risk one') → case-insensitive substring match on the Job Title field. If multiple jobs match, prefer the earliest. Only if no reasonable match exists, ask a one-line clarifying question. Then pass that job's **Job Id** value from the prior search result's content text VERBATIM as job_id to job_detail_tool / tailor_resume_tool / cover_letter_tool. Do NOT invent a placeholder like 'JOB_1' or '#1' — those are not server-valid IDs. For save, pass job_id + optional job_title/company/job_url in save_job. Put search fields in search_jobs or parameters; refine in refine_recommendations; save in save_job.…
Overall 77/100. Components that don't apply are left out of the denominator. Any critical finding is an F.RubricAppeal a findingJSON

What the publisher says

From the Workopia — Job Search repository's README, as published. We do not edit it. Read it on GitHub

Workopia MCP Server

Job search, resume tailoring, cover letters & application tracking — available via the Model Context Protocol for Claude Code, Claude Desktop, Cursor, Windsurf, and other MCP clients.

Note: This is a hosted MCP server. Connect via the public endpoint below and sign in with Workopia (OAuth) — no API key to manage. All tools require a free Workopia sign-in; searching, job detail, resume tailoring, cover letters, and your dashboard are all scoped to your account. Resume tailoring and cover letters run on your own AI client's model — Workopia hosts no LLM and never charges for AI.

Endpoint

https://workopia.io/api/mcp-jobs
  • Transport: Streamable HTTP
  • Auth: OAuth 2.0 (Dynamic Client Registration + PKCE; handled automatically by the client)
  • Website: https://workopia.io

Install as a Claude Code plugin

/plugin marketplace add workopia/workopia-mcp
/plugin install workopia-jobs

On first tool use, Claude Code opens the Workopia OAuth flow in your browser; the token is then stored and refreshed automatically.

Sign up and sign in

There is no separate GitHub-repository account and no API key to create. The first time an MCP client calls a Workopia tool, it opens the Workopia authorization page in your browser. Sign in with an email code, Google, LinkedIn, or GitHub.

  • If that verified email already has a Workopia profile, the MCP connection uses it.
  • Otherwise Workopia creates a minimal profile for that verified email.
  • The MCP client stores and refreshes its OAuth token. Disconnect or remove Workopia in the client to revoke its local connection.
  • Using the same verified email from another supported client connects activity to the same Workopia profile; it does not create a separate MCP-only account.

OAuth uses Authorization Code + PKCE and Dynamic Client Registration. Never paste a Workopia password, email code, OAuth token, or resume into this repository or a GitHub issue.

Tools

Quick start (manual config)

Claude Desktop — add to claudedesktopconfig.json:

{
  "mcpServers": {
    "workopia": {
      "type": "streamable-http",
      "url": "https://workopia.io/api/mcp-jobs"
    }
  }
}

Cursor — .cursor/mcp.json:

{
  "mcpServers": {
    "workopia": { "url": "https://workopia.io/api/mcp-jobs" }
  }
}

ChatGPT — search "Workopia" in the ChatGPT App Store.

Also listed on

  • MCP Registry: io.github.Shuangshuang007/workopia
  • npm: @shuang_workopia/workopia-mcp
  • OpenClaw ClawHub: Shuangshuang007/workopia

Live on Glama

Quota

Free at launch. A free Workopia sign-in (OAuth) is required to use the tools — searching, job detail, resume tailoring, cover letters, and your dashboard. Need a higher quota or a custom arrangement? Email shuang@heraai.one.

Account activity and privacy

Shortened. The full README is on GitHub.

Nothing above is checked by us. What we check is on the safety report.

Install directly

claude mcp add --transport http workopia-mcp https://workopia.io/api/mcp-jobs
Add to Cursor

Workopia — Job Search: common questions

Is Workopia — Job Search MCP server safe?
Mostly: it is graded B (77/100). Read the Workopia — Job Search safety report
How do I install Workopia — Job Search?
It runs remotely at workopia.io. Add it to Claude Code, Claude Desktop or Cursor with the snippets above, or call it through the mcp.market gateway without installing anything.
Does Workopia — Job Search need an API key?
Not as far as the registry entry and our scan can tell: no credentials are declared or required.
Is Workopia — Job Search maintained?
The last commit was 27 days ago (2026-08-31). The latest release is v1.0.2.
Is Workopia — Job Search up?
100% of our last 28 checks got an answer. We check remote servers about four times a day.
What can I use instead of Workopia — Job Search?
Servers from other publishers that do the same job: Jobseek MCP server, Trackly CLI MCP server and Web Search MCP server. Compare all Workopia — Job Search alternatives.

Alternatives to Workopia — Job Search

Same job from other publishers: the closest match first, then the best rated.

All Workopia — Job Search alternatives →
  • Jobseek
    Search jobs and companies on Job Seek (jseek.co)
    A
  • Trackly CLI
    Job search for Claude, ChatGPT, Cursor. 250K+ jobs, 5,400+ companies. OAuth or stdio.
    A
  • Web Search
    Live web search and clean-markdown page fetch over the Keenable web index.
    A
  • Cronus UI
    Search, install, compose, add-page, and theme Cronus UI from the live registry.
    A
  • LetsFG — Flights & Hotels
    Search and book flights and hotels: hundreds of airlines, plus bookable hotel rates.
    A

More from workopia →